lcGeneric.c revision 1ab64890
1/* $Xorg: lcGeneric.c,v 1.7 2000/12/12 12:44:05 coskrey Exp $ */
2/*
3 * Copyright 1992, 1993 by TOSHIBA Corp.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation for any purpose and without fee is hereby granted, provided
7 * that the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of TOSHIBA not be used in advertising
10 * or publicity pertaining to distribution of the software without specific,
11 * written prior permission. TOSHIBA make no representations about the
12 * suitability of this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 *
15 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21 * SOFTWARE.
22 *
23 * Author: Katsuhisa Yano	TOSHIBA Corp.
24 *			   	mopi@osa.ilab.toshiba.co.jp
25 */
26/*
27 *  (c) Copyright 1995 FUJITSU LIMITED
28 *  This is source code modified by FUJITSU LIMITED under the Joint
29 *  Development Agreement for the CDE/Motif PST.
30 */
31/* $XFree86: xc/lib/X11/lcGeneric.c,v 3.19 2003/05/27 16:55:27 tsi Exp $ */
32
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36#include <stdio.h>
37#include "Xlibint.h"
38#include "XlcGeneric.h"
39
40static XLCd create (const char *name, XLCdMethods methods);
41static Bool initialize (XLCd lcd);
42static void destroy (XLCd lcd);
43
44static XLCdPublicMethodsRec genericMethods = {
45    { NULL },                   /* use default methods */
46    {
47	NULL,
48	create,
49	initialize,
50	destroy,
51	NULL
52    }
53};
54
55XLCdMethods _XlcGenericMethods = (XLCdMethods) &genericMethods;
56
57static XLCd
58create(
59    const char *name,
60    XLCdMethods methods)
61{
62    XLCd lcd;
63    XLCdPublicMethods new;
64
65    lcd = (XLCd) Xmalloc(sizeof(XLCdRec));
66    if (lcd == NULL)
67        return (XLCd) NULL;
68    bzero((char *) lcd, sizeof(XLCdRec));
69
70    lcd->core = (XLCdCore) Xmalloc(sizeof(XLCdGenericRec));
71    if (lcd->core == NULL)
72	goto err;
73    bzero((char *) lcd->core, sizeof(XLCdGenericRec));
74
75    new = (XLCdPublicMethods) Xmalloc(sizeof(XLCdPublicMethodsRec));
76    if (new == NULL)
77	goto err;
78    memcpy(new,methods,sizeof(XLCdPublicMethodsRec));
79    lcd->methods = (XLCdMethods) new;
80
81    return lcd;
82
83err:
84    Xfree(lcd);
85    return (XLCd) NULL;
86}
87
88static Bool
89string_to_encoding(
90    const char *str,
91    char *encoding)
92{
93    char *next;
94    long value;
95    int base;
96
97    while (*str) {
98	if (*str == '\\') {
99	    switch (*(str + 1)) {
100		case 'x':
101		case 'X':
102		    base = 16;
103		    break;
104		default:
105		    base = 8;
106		    break;
107	    }
108	    value = strtol(str + 2, &next, base);
109	    if (str + 2 != next) {
110		*((unsigned char *) encoding++) = (unsigned char) value;
111		str = next;
112		continue;
113	    }
114	}
115	*encoding++ = *str++;
116    }
117
118    *encoding = '\0';
119
120    return True;
121}
122
123static Bool
124string_to_ulong(
125    const char *str,
126    unsigned long *value)
127{
128     const char *tmp1 = str;
129     int base;
130
131     if (*tmp1++ != '\\') {
132	  tmp1--;
133	  base = 10;
134     } else {
135	  switch (*tmp1++) {
136	  case 'x':
137	       base = 16;
138	       break;
139	  case 'o':
140	       base = 8;
141	       break;
142	  case 'd':
143	       base = 10;
144	       break;
145	  default:
146	       return(False);
147	  }
148     }
149     *value = (unsigned long) strtol(tmp1, NULL, base);
150     return(True);
151}
152
153
154static Bool
155add_charset(
156    CodeSet codeset,
157    XlcCharSet charset)
158{
159    XlcCharSet *new_list;
160    int num;
161
162    if ((num = codeset->num_charsets))
163        new_list = (XlcCharSet *) Xrealloc(codeset->charset_list,
164                                        (num + 1) * sizeof(XlcCharSet));
165    else
166        new_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet));
167
168    if (new_list == NULL)
169	return False;
170
171    new_list[num] = charset;
172    codeset->charset_list = new_list;
173    codeset->num_charsets = num + 1;
174
175    return True;
176}
177
178static CodeSet
179add_codeset(
180    XLCdGenericPart *gen)
181{
182    CodeSet new, *new_list;
183    int num;
184
185    new = (CodeSet) Xmalloc(sizeof(CodeSetRec));
186    if (new == NULL)
187        return NULL;
188    bzero((char *) new, sizeof(CodeSetRec));
189
190    if ((num = gen->codeset_num))
191        new_list = (CodeSet *) Xrealloc(gen->codeset_list,
192                                        (num + 1) * sizeof(CodeSet));
193    else
194        new_list = (CodeSet *) Xmalloc(sizeof(CodeSet));
195
196    if (new_list == NULL)
197        goto err;
198
199    new_list[num] = new;
200    gen->codeset_list = new_list;
201    gen->codeset_num = num + 1;
202
203    return new;
204
205err:
206    Xfree(new);
207
208    return NULL;
209}
210
211static Bool
212add_parse_list(
213    XLCdGenericPart *gen,
214    EncodingType type,
215    const char *encoding,
216    CodeSet codeset)
217{
218    ParseInfo new, *new_list;
219    char *str;
220    unsigned char ch;
221    int num;
222
223    str = (char *) Xmalloc(strlen(encoding) + 1);
224    if (str == NULL)
225        return False;
226    strcpy(str, encoding);
227
228    new = (ParseInfo) Xmalloc(sizeof(ParseInfoRec));
229    if (new == NULL)
230        goto err;
231    bzero((char *) new, sizeof(ParseInfoRec));
232
233    if (gen->mb_parse_table == NULL) {
234        gen->mb_parse_table = (unsigned char *) Xmalloc(256); /* 2^8 */
235        if (gen->mb_parse_table == NULL)
236            goto err;
237        bzero((char *) gen->mb_parse_table, 256);
238    }
239
240    if ((num = gen->mb_parse_list_num))
241        new_list = (ParseInfo *) Xrealloc(gen->mb_parse_list,
242                                          (num + 2) * sizeof(ParseInfo));
243    else {
244        new_list = (ParseInfo *) Xmalloc(2 * sizeof(ParseInfo));
245    }
246
247    if (new_list == NULL)
248        goto err;
249
250    new_list[num] = new;
251    new_list[num + 1] = NULL;
252    gen->mb_parse_list = new_list;
253    gen->mb_parse_list_num = num + 1;
254
255    ch = (unsigned char) *str;
256    if (gen->mb_parse_table[ch] == 0)
257        gen->mb_parse_table[ch] = num + 1;
258
259    new->type = type;
260    new->encoding = str;
261    new->codeset = codeset;
262
263    if (codeset->parse_info == NULL)
264        codeset->parse_info = new;
265
266    return True;
267
268err:
269    Xfree(str);
270    if (new)
271        Xfree(new);
272
273    return False;
274}
275
276static void
277free_charset(
278    XLCd lcd)
279{
280    XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
281    ParseInfo *parse_info;
282    int num;
283
284    if (gen->mb_parse_table)
285        Xfree(gen->mb_parse_table);
286    if ((num = gen->mb_parse_list_num) > 0) {
287        for (parse_info = gen->mb_parse_list; num-- > 0; parse_info++) {
288            if ((*parse_info)->encoding)
289                Xfree((*parse_info)->encoding);
290            Xfree(*parse_info);
291        }
292        Xfree(gen->mb_parse_list);
293    }
294
295    if ((num = gen->codeset_num) > 0)
296        Xfree(gen->codeset_list);
297}
298
299/* For VW/UDC */
300
301#define FORWARD  (unsigned long)'+'
302#define BACKWARD (unsigned long)'-'
303
304static const char *
305getscope(
306    const char *str,
307    FontScope scp)
308{
309    unsigned long start = 0;
310    unsigned long end = 0;
311    unsigned long dest = 0;
312    unsigned long shift = 0;
313    unsigned long direction = 0;
314    sscanf(str,"[\\x%lx,\\x%lx]->\\x%lx", &start, &end, &dest);
315    if (dest) {
316        if (dest >= start) {
317            shift = dest - start;
318            direction = FORWARD ;
319        } else {
320            shift = start - dest;
321            direction = BACKWARD;
322        }
323    }
324    scp->start = start      ;
325    scp->end   = end        ;
326    scp->shift = shift      ;
327    scp->shift_direction
328               = direction  ;
329    /* .......... */
330    while (*str) {
331        if (*str == ',' && *(str+1) == '[')
332            break;
333        str++;
334    }
335    return str+1;
336}
337
338static int
339count_scopemap(
340    const char *str)
341{
342    const char *ptr;
343    int num=0;
344    for (ptr=str; *ptr; ptr++) {
345        if (*ptr == ']') {
346            num++;
347        }
348    }
349    return num;
350}
351
352FontScope
353_XlcParse_scopemaps(
354    const char *str,
355    int *size)
356{
357    int num=0,i;
358    FontScope scope,sc_ptr;
359    const char *str_sc;
360
361    num = count_scopemap(str);
362    scope = (FontScope) Xmalloc(num * sizeof(FontScopeRec));
363    if (scope == NULL)
364	return NULL;
365
366    for (i=0, str_sc=str, sc_ptr=scope; i < num; i++, sc_ptr++) {
367	str_sc = getscope(str_sc, sc_ptr);
368    }
369    *size = num;
370    return scope;
371}
372
373void
374_XlcDbg_printValue(
375    const char *str,
376    char **value,
377    int num)
378{
379/*
380    int i;
381    for (i = 0; i < num; i++)
382        fprintf(stderr, "%s value[%d] = %s\n", str, i, value[i]);
383*/
384}
385
386static void
387dmpscope(
388    const char* name,
389    FontScope sc,
390    int num)
391{
392/*
393    int i;
394    fprintf(stderr, "dmpscope %s\n", name);
395    for (i=0; i<num; i++)
396        fprintf(stderr,"%x %x %x %x \n",
397                sc[i].start,
398                sc[i].end,
399                sc[i].shift,
400                sc[i].shift_direction);
401    fprintf(stderr, "dmpscope end\n");
402*/
403}
404
405static XlcCharSet
406srch_charset_define(
407    const char *name,
408    int *new)
409{
410    XlcCharSet charset;
411
412    *new = 0;
413    charset = _XlcGetCharSet(name);
414    if (charset == NULL &&
415        (charset = _XlcCreateDefaultCharSet(name, ""))) {
416        _XlcAddCharSet(charset);
417        *new = 1;
418        charset->source = CSsrcXLC;
419    }
420    return charset;
421}
422
423static void
424read_charset_define(
425    XLCd lcd,
426    XLCdGenericPart *gen)
427{
428    int i;
429    char csd[16], cset_name[256];
430    char name[BUFSIZ];
431    XlcCharSet charsetd;
432    char **value;
433    int num, new;
434    XlcSide side = XlcUnknown;
435    char *tmp;
436
437    for (i=0; ; i++) { /* loop start */
438        charsetd = 0;
439        sprintf(csd, "csd%d", i);
440
441        /* charset_name  */
442        sprintf(name, "%s.%s", csd, "charset_name");
443        _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
444        _XlcDbg_printValue(name,value,num);
445        if (num > 0) {
446	    /* hackers will get truncated -- C'est la vie */
447            strncpy(cset_name,value[0], sizeof cset_name - 1);
448	    cset_name[(sizeof cset_name) - 1] = '\0';
449            sprintf(name, "%s.%s", csd , "side");
450            _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
451            if (num > 0) {
452                _XlcDbg_printValue(name,value,num);
453                if (!_XlcNCompareISOLatin1(value[0], "none", 4)) {
454                    side =  XlcGLGR;
455                } else if (!_XlcNCompareISOLatin1(value[0], "GL", 2)) {
456                    side =  XlcGL;
457                    strcat(cset_name,":GL");
458                } else {
459                    side =  XlcGR;
460                    strcat(cset_name,":GR");
461                }
462                if (charsetd == NULL &&
463                    (charsetd = srch_charset_define(cset_name,&new)) == NULL)
464                    return;
465            }
466        } else {
467            if (i == 0)
468                continue;
469            else
470                break;
471        }
472        if (new) {
473            tmp = (char *)Xmalloc(strlen(cset_name)+1);
474            if (tmp == NULL)
475                return;
476            strcpy(tmp,cset_name);
477            charsetd->name = tmp;
478        }
479        /* side   */
480        charsetd->side = side ;
481        /* length */
482        sprintf(name, "%s.%s", csd, "length");
483        _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
484        if (num > 0) {
485            _XlcDbg_printValue(name,value,num);
486            charsetd->char_size = atoi(value[0]);
487        }
488        /* gc_number */
489        sprintf(name, "%s.%s", csd, "gc_number");
490        _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
491        if (num > 0) {
492            _XlcDbg_printValue(name,value,num);
493            charsetd->set_size = atoi(value[0]);
494        }
495        /* string_encoding */
496        sprintf(name, "%s.%s", csd, "string_encoding");
497        _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
498        if (num > 0) {
499            _XlcDbg_printValue(name,value,num);
500            if (!strcmp("False",value[0])) {
501                charsetd->string_encoding = False;
502            } else {
503                charsetd->string_encoding = True;
504            }
505        }
506        /* sequence */
507        sprintf(name, "%s.%s", csd, "sequence");
508        _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
509        if (num > 0) {
510            _XlcDbg_printValue(name,value,num);
511/*
512            if (charsetd->ct_sequence) {
513                Xfree(charsetd->ct_sequence);
514            }
515*/
516            tmp = (char *)Xmalloc(strlen(value[0])+1);
517            if (tmp == NULL)
518                return;
519            charsetd->ct_sequence = tmp;
520            string_to_encoding(value[0],tmp);
521        }
522        /* encoding_name */
523        sprintf(name, "%s.%s", csd, "encoding_name");
524        _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
525        if (num > 0) {
526            _XlcDbg_printValue(name,value,num);
527/*
528            if (charsetd->encoding_name) {
529                Xfree(charsetd->encoding_name);
530            }
531*/
532            tmp = (char *)Xmalloc(strlen(value[0])+1);
533            strcpy(tmp,value[0]);
534            charsetd->encoding_name = tmp;
535            charsetd->xrm_encoding_name = XrmStringToQuark(tmp);
536        }
537        _XlcAddCT(charsetd->name, charsetd->ct_sequence);
538    }
539}
540
541static SegConv
542add_conversion(
543    XLCdGenericPart *gen)
544{
545    SegConv new_list;
546    int num;
547
548    if ((num = gen->segment_conv_num) > 0) {
549        new_list = (SegConv) Xrealloc(gen->segment_conv,
550                                        (num + 1) * sizeof(SegConvRec));
551    } else {
552        new_list = (SegConv) Xmalloc(sizeof(SegConvRec));
553    }
554
555    if (new_list == NULL)
556        return NULL;
557
558    gen->segment_conv = new_list;
559    gen->segment_conv_num = num + 1;
560
561    return &new_list[num];
562
563}
564
565static void
566read_segmentconversion(
567    XLCd lcd,
568    XLCdGenericPart *gen)
569{
570    int i;
571    char conv[16];
572    char name[BUFSIZ];
573    char **value;
574    int num,new;
575    SegConv conversion;
576    for (i=0 ; ; i++) { /* loop start */
577        conversion = 0;
578        sprintf(conv, "conv%d", i);
579
580        /* length                */
581        sprintf(name, "%s.%s", conv, "length");
582        _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
583        if (num > 0) {
584            if (conversion == NULL &&
585                (conversion = add_conversion(gen)) == NULL) {
586                return;
587            }
588            _XlcDbg_printValue(name,value,num);
589        } else {
590            if (i == 0)
591                continue;
592            else
593                break;
594        }
595        conversion->length = atoi(value[0]);
596
597        /* source_encoding       */
598        sprintf(name, "%s.%s", conv, "source_encoding");
599        _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
600        if (num > 0) {
601            char *tmp;
602            _XlcDbg_printValue(name,value,num);
603            tmp = (char *)Xmalloc(strlen(value[0])+1);
604            if (tmp == NULL)
605                return;
606            strcpy(tmp,value[0]);
607            conversion->source_encoding = tmp;
608            conversion->source = srch_charset_define(tmp,&new);
609        }
610        /* destination_encoding  */
611        sprintf(name, "%s.%s", conv, "destination_encoding");
612        _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
613        if (num > 0) {
614            char *tmp;
615            _XlcDbg_printValue(name,value,num);
616            tmp = (char *)Xmalloc(strlen(value[0])+1);
617            if (tmp == NULL)
618                return;
619            strcpy(tmp,value[0]);
620            conversion->destination_encoding = tmp;
621            conversion->dest = srch_charset_define(tmp,&new);
622        }
623        /* range                 */
624        sprintf(name, "%s.%s", conv, "range");
625        _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
626        if (num > 0) {
627            _XlcDbg_printValue(name,value,num);
628            sscanf(value[0],"\\x%lx,\\x%lx",
629                   &(conversion->range.start), &(conversion->range.end));
630        }
631        /* conversion            */
632        sprintf(name, "%s.%s", conv, "conversion");
633        _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
634        if (num > 0) {
635            _XlcDbg_printValue(name,value,num);
636            conversion->conv =
637                _XlcParse_scopemaps(value[0],&conversion->conv_num);
638        }
639    }  /* loop end */
640}
641
642static ExtdSegment
643create_ctextseg(
644    char **value,
645    int num)
646{
647    ExtdSegment ret;
648    char* ptr;
649    char* cset_name = NULL;
650    int i,new;
651    FontScope scope;
652    ret = (ExtdSegment)Xmalloc(sizeof(ExtdSegmentRec));
653    if (ret == NULL)
654        return NULL;
655    ret->name = (char *)Xmalloc(strlen(value[0]) + 1);
656    if (ret->name == NULL) {
657        Xfree (ret);
658        return NULL;
659    }
660    strcpy(ret->name,value[0]);
661    cset_name = (char*) Xmalloc (strlen(ret->name) + 1);
662    if (cset_name == NULL) {
663        Xfree (ret->name);
664        Xfree (ret);
665        return NULL;
666    }
667    if (strchr(value[0],':')) {
668        ptr = strchr(ret->name,':');
669        *ptr = '\0';
670        ptr++;
671        if (!_XlcNCompareISOLatin1(ptr, "GL", 2)) {
672            ret->side =  XlcGL;
673            sprintf(cset_name,"%s:%s",ret->name,"GL");
674        } else {
675            ret->side =  XlcGR;
676            sprintf(cset_name,"%s:%s",ret->name,"GR");
677        }
678    } else {
679        ret->side =  XlcGLGR;
680        strcpy(cset_name,ret->name);
681    }
682    ret->area = (FontScope)Xmalloc((num - 1)*sizeof(FontScopeRec));
683    if (ret->area == NULL) {
684	Xfree (cset_name);
685	Xfree (ret->name);
686	Xfree (ret);
687        return NULL;
688    }
689    ret->area_num = num - 1;
690    scope = ret->area ;
691    for (i = 1; i < num; i++) {
692        sscanf(value[i],"\\x%lx,\\x%lx",
693               &scope[i-1].start, &scope[i-1].end);
694    }
695    ret->charset = srch_charset_define(cset_name,&new);
696    Xfree (cset_name);
697
698    return ret;
699}
700/* For VW/UDC end */
701
702static Bool
703load_generic(
704    XLCd lcd)
705{
706    XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
707    char **value;
708    int num;
709    unsigned long l;
710    int i;
711    int M,ii;
712    XlcCharSet charset;
713
714    gen->codeset_num = 0;
715
716    /***** wc_encoding_mask *****/
717    _XlcGetResource(lcd, "XLC_XLOCALE", "wc_encoding_mask", &value, &num);
718    if (num > 0) {
719	if (string_to_ulong(value[0], &l) == False)
720	    goto err;
721	gen->wc_encode_mask = l;
722    }
723    /***** wc_shift_bits *****/
724    _XlcGetResource(lcd, "XLC_XLOCALE", "wc_shift_bits", &value, &num);
725    if (num > 0)
726	gen->wc_shift_bits = atoi(value[0]);
727    if (gen->wc_shift_bits < 1)
728	gen->wc_shift_bits = 8;
729    /***** use_stdc_env *****/
730    _XlcGetResource(lcd, "XLC_XLOCALE", "use_stdc_env", &value, &num);
731    if (num > 0 && !_XlcCompareISOLatin1(value[0], "True"))
732	gen->use_stdc_env = True;
733    else
734	gen->use_stdc_env = False;
735    /***** force_convert_to_mb *****/
736    _XlcGetResource(lcd, "XLC_XLOCALE", "force_convert_to_mb", &value, &num);
737    if (num > 0 && !_XlcCompareISOLatin1(value[0], "True"))
738	gen->force_convert_to_mb = True;
739    else
740	gen->force_convert_to_mb = False;
741
742    for (i = 0; ; i++) {
743	CodeSetRec *codeset = NULL;
744	char cs[16];
745	char name[BUFSIZ];
746
747	sprintf(cs, "cs%d", i);
748
749	/***** codeset.side *****/
750	sprintf(name, "%s.%s", cs , "side");
751	_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
752	if (num > 0) {
753	    char *tmp;
754
755	    if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
756		goto err;
757
758            /* 3.4.1 side */
759            if (!_XlcNCompareISOLatin1(value[0], "none", 4)) {
760                codeset->side =  XlcNONE;
761            } else if (!_XlcNCompareISOLatin1(value[0], "GL", 2)) {
762                codeset->side =  XlcGL;
763            } else {
764                codeset->side =  XlcGR;
765            }
766
767	    tmp = strrchr(value[0], ':');
768	    if (tmp != NULL && !_XlcCompareISOLatin1(tmp + 1, "Default")) {
769		if (codeset->side == XlcGR)
770		    gen->initial_state_GR = codeset;
771		else
772		    gen->initial_state_GL = codeset;
773	    }
774	}
775
776	/***** codeset.length *****/
777	sprintf(name, "%s.%s", cs , "length");
778	_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
779	if (num > 0) {
780	    if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
781		goto err;
782	    codeset->length = atoi(value[0]);
783	    if (codeset->length < 1)
784		codeset->length = 1;
785	}
786
787	/***** codeset.mb_encoding *****/
788	sprintf(name, "%s.%s", cs, "mb_encoding");
789	_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
790	if (num > 0) {
791	    static struct {
792		const char *str;
793		EncodingType type;
794	    } shifts[] = {
795		{"<SS>", E_SS},
796		{"<LSL>", E_LSL},
797		{"<LSR>", E_LSR},
798		{0}
799	    };
800	    int j;
801
802	    if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
803		goto err;
804	    for ( ; num-- > 0; value++) {
805		char encoding[256];
806		char *tmp = *value;
807		EncodingType type = E_SS;    /* for BC */
808		for (j = 0; shifts[j].str; j++) {
809		    if (!_XlcNCompareISOLatin1(tmp, shifts[j].str,
810					       strlen(shifts[j].str))) {
811			type = shifts[j].type;
812			tmp += strlen(shifts[j].str);
813			break;
814		    }
815		}
816		if (strlen (tmp) > sizeof encoding ||
817		    string_to_encoding(tmp, encoding) == False)
818			goto err;
819		add_parse_list(gen, type, encoding, codeset);
820	    }
821	}
822
823	/***** codeset.wc_encoding *****/
824	sprintf(name, "%s.%s", cs, "wc_encoding");
825	_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
826	if (num > 0) {
827	    if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
828		goto err;
829	    if (string_to_ulong(value[0], &l) == False)
830		goto err;
831	    codeset->wc_encoding = l;
832	}
833
834	/***** codeset.ct_encoding *****/
835	sprintf(name, "%s.%s", cs, "ct_encoding");
836	_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
837	if (num > 0) {
838	    char *encoding;
839
840	    if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
841		goto err;
842	    for ( ; num-- > 0; value++) {
843		if (strlen (*value) > sizeof name)
844		    goto err;
845		string_to_encoding(*value, name);
846		charset = NULL;
847		if ((encoding = strchr(name, ':')) &&
848		    (encoding = strchr(encoding + 1, ':'))) {
849		    *encoding++ = '\0';
850		    charset = _XlcAddCT(name, encoding);
851		}
852		if (charset == NULL) {
853		    charset = _XlcGetCharSet(name);
854		    if (charset == NULL &&
855			(charset = _XlcCreateDefaultCharSet(name, ""))) {
856			charset->side = codeset->side;
857			charset->char_size = codeset->length;
858			_XlcAddCharSet(charset);
859		    }
860		}
861		if (charset) {
862		    if (add_charset(codeset, charset) == False)
863			goto err;
864		}
865	    }
866	}
867
868	if (codeset == NULL)
869	    break;
870	codeset->cs_num = i;
871        /* For VW/UDC */
872        /***** 3.4.2 byteM (1 <= M <= length)*****/
873        for (M=1; M-1  < codeset->length; M++) {
874            unsigned long start,end;
875            ByteInfo tmpb;
876
877            sprintf(name,"%s.%s%d",cs,"byte",M);
878            _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
879
880            if (M == 1) {
881                if (num < 1) {
882                    codeset->byteM = NULL;
883                    break ;
884                }
885                codeset->byteM =
886                    (ByteInfoListRec *)Xmalloc(
887                         (codeset->length)*sizeof(ByteInfoListRec));
888                if (codeset->byteM == NULL) {
889                    goto err;
890                }
891            }
892
893            if (num > 0) {
894                _XlcDbg_printValue(name,value,num);
895                (codeset->byteM)[M-1].M = M;
896                (codeset->byteM)[M-1].byteinfo_num = num;
897                (codeset->byteM)[M-1].byteinfo =
898                    (ByteInfo)Xmalloc( num * sizeof(ByteInfoRec));
899                for (ii = 0 ; ii < num ; ii++) {
900                    tmpb = (codeset->byteM)[M-1].byteinfo ;
901                    /* default 0x00 - 0xff */
902                    sscanf(value[ii],"\\x%lx,\\x%lx",&start,&end);
903                    tmpb[ii].start = (unsigned char)start;
904                    tmpb[ii].end  = (unsigned char)end;
905                }
906            }
907            /* .... */
908        }
909
910
911        /***** codeset.mb_conversion *****/
912        sprintf(name, "%s.%s", cs, "mb_conversion");
913        _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
914        if (num > 0) {
915                _XlcDbg_printValue(name,value,num);
916                codeset->mbconv = Xmalloc(sizeof(ConversionRec));
917                codeset->mbconv->convlist =
918                _XlcParse_scopemaps(value[0],&(codeset->mbconv->conv_num));
919                dmpscope("mb_conv",codeset->mbconv->convlist,
920                         codeset->mbconv->conv_num);
921                /* [\x%x,\x%x]->\x%x,... */
922        }
923        /***** codeset.ct_conversion *****/
924        sprintf(name, "%s.%s", cs, "ct_conversion");
925        _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
926        if (num > 0) {
927                _XlcDbg_printValue(name,value,num);
928                codeset->ctconv = Xmalloc(sizeof(ConversionRec));
929                codeset->ctconv->convlist =
930                _XlcParse_scopemaps(value[0],&(codeset->ctconv->conv_num));
931                dmpscope("ctconv",codeset->ctconv->convlist,
932                         codeset->ctconv->conv_num);
933                /* [\x%x,\x%x]->\x%x,... */
934        }
935        /***** codeset.ct_conversion_file *****/
936        sprintf(name, "%s.%s", cs, "ct_conversion_file");
937        _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
938        if (num > 0) {
939                _XlcDbg_printValue(name,value,num);
940                /* [\x%x,\x%x]->\x%x,... */
941        }
942        /***** codeset.ct_extended_segment *****/
943        sprintf(name, "%s.%s", cs, "ct_extended_segment");
944        _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
945        if (num > 0) {
946                _XlcDbg_printValue(name,value,num);
947                codeset->ctextseg = create_ctextseg(value,num);
948                /* [\x%x,\x%x]->\x%x,... */
949        }
950        /* For VW/UDC end */
951
952    }
953
954    read_charset_define(lcd,gen);       /* For VW/UDC */
955    read_segmentconversion(lcd,gen);    /* For VW/UDC */
956
957    if (gen->initial_state_GL == NULL) {
958       CodeSetRec *codeset;
959       for (i = 0; i < gen->codeset_num; i++) {
960          codeset = gen->codeset_list[i];
961          if (codeset->side == XlcGL)
962             gen->initial_state_GL = codeset;
963       }
964    }
965
966    if (gen->initial_state_GR == NULL) {
967       CodeSetRec *codeset;
968       for (i = 0; i < gen->codeset_num; i++) {
969          codeset = gen->codeset_list[i];
970          if (codeset->side == XlcGR)
971             gen->initial_state_GR = codeset;
972       }
973    }
974
975    for (i = 0; i < gen->codeset_num; i++) {
976       CodeSetRec *codeset = gen->codeset_list[i];
977       for (ii = 0; ii < codeset->num_charsets; ii++) {
978          charset = codeset->charset_list[ii];
979          if (! strcmp(charset->encoding_name, "ISO8859-1"))
980              charset->string_encoding = True;
981          if ( charset->string_encoding )
982              codeset->string_encoding = True;
983       }
984    }
985    return True;
986
987err:
988    free_charset(lcd);
989
990    return False;
991}
992
993#ifdef USE_DYNAMIC_LC
994/* override the open_om and open_im methods which were set by
995   super_class's initialize method() */
996
997static Bool
998initialize_core(
999    XLCd lcd)
1000{
1001    _XInitDynamicOM(lcd);
1002
1003    _XInitDynamicIM(lcd);
1004
1005    return True;
1006}
1007#endif
1008
1009static Bool
1010initialize(lcd)
1011    XLCd lcd;
1012{
1013    XLCdPublicMethods superclass = (XLCdPublicMethods) _XlcPublicMethods;
1014
1015    XLC_PUBLIC_METHODS(lcd)->superclass = superclass;
1016
1017    if (superclass->pub.initialize) {
1018	if ((*superclass->pub.initialize)(lcd) == False)
1019	    return False;
1020    }
1021
1022#ifdef USE_DYNAMIC_LC
1023    if (initialize_core(lcd) == False)
1024	return False;
1025#endif
1026
1027    if (load_generic(lcd) == False)
1028	return False;
1029
1030    return True;
1031}
1032
1033/* VW/UDC start 95.01.08 */
1034static void
1035freeByteM(
1036    CodeSet codeset)
1037{
1038    int i;
1039    ByteInfoList blst;
1040    if (codeset->byteM == NULL) {
1041	return ;
1042    }
1043    blst = codeset->byteM;
1044    for (i = 0; i < codeset->length; i++) {
1045	if (blst[i].byteinfo) {
1046	    Xfree(blst[i].byteinfo);
1047	    blst[i].byteinfo = NULL;
1048	}
1049    }
1050    Xfree(codeset->byteM);
1051    codeset->byteM = NULL;
1052}
1053
1054static void
1055freeConversion(
1056    CodeSet codeset)
1057{
1058    Conversion mbconv,ctconv;
1059    if (codeset->mbconv) {
1060	mbconv = codeset->mbconv;
1061	/*  ...  */
1062	if (mbconv->convlist) {
1063	    Xfree(mbconv->convlist);
1064	    mbconv->convlist = NULL;
1065	}
1066	Xfree(mbconv);
1067	codeset->mbconv = NULL;
1068    }
1069    if (codeset->ctconv) {
1070	ctconv = codeset->ctconv;
1071	/*  ...  */
1072	if (ctconv->convlist) {
1073	    Xfree(ctconv->convlist);
1074	    ctconv->convlist = NULL;
1075	}
1076	Xfree(ctconv);
1077	codeset->ctconv = NULL;
1078    }
1079}
1080
1081static void
1082freeExtdSegment(
1083    CodeSet codeset)
1084{
1085    ExtdSegment ctextseg;
1086    if (codeset->ctextseg == NULL) {
1087	return;
1088    }
1089    ctextseg = codeset->ctextseg;
1090    if (ctextseg->name) {
1091	Xfree(ctextseg->name);
1092	ctextseg->name = NULL;
1093    }
1094    if (ctextseg->area) {
1095	Xfree(ctextseg->area);
1096	ctextseg->area = NULL;
1097    }
1098    Xfree(codeset->ctextseg);
1099    codeset->ctextseg = NULL;
1100}
1101
1102static void
1103freeParseInfo(
1104    CodeSet codeset)
1105{
1106    ParseInfo parse_info;
1107    if (codeset->parse_info == NULL) {
1108	return;
1109    }
1110    parse_info = codeset->parse_info;
1111    if (parse_info->encoding) {
1112	Xfree(parse_info->encoding);
1113	parse_info->encoding = NULL;
1114    }
1115    Xfree(codeset->parse_info);
1116    codeset->parse_info = NULL;
1117}
1118
1119static void
1120destroy_CodeSetList(
1121    XLCdGenericPart *gen)
1122{
1123    CodeSet *codeset = gen->codeset_list;
1124    int i;
1125    if (gen->codeset_num == 0) {
1126	return;
1127    }
1128    for (i=0;i<gen->codeset_num;i++) {
1129        freeByteM(codeset[i]);
1130	freeConversion(codeset[i]);
1131	freeExtdSegment(codeset[i]);
1132	freeParseInfo(codeset[i]);
1133	if (codeset[i]->charset_list) {
1134	    Xfree(codeset[i]->charset_list);
1135	    codeset[i]->charset_list = NULL;
1136	}
1137	Xfree(codeset[i]); codeset[i]=NULL;
1138    }
1139    Xfree(codeset); gen->codeset_list = NULL;
1140}
1141
1142static void
1143destroy_SegConv(
1144    XLCdGenericPart *gen)
1145{
1146    SegConv seg = gen->segment_conv;
1147    int i;
1148    if (gen->segment_conv_num == 0) {
1149	return;
1150    }
1151    for (i=0;i<gen->segment_conv_num;i++) {
1152	if (seg[i].source_encoding) {
1153	    Xfree(seg[i].source_encoding);
1154	    seg[i].source_encoding = NULL;
1155	}
1156	if (seg[i].destination_encoding) {
1157	    Xfree(seg[i].destination_encoding);
1158	    seg[i].destination_encoding = NULL;
1159	}
1160	if (seg[i].conv) {
1161	    Xfree(seg[i].conv); seg[i].conv = NULL;
1162	}
1163    }
1164    Xfree(seg); gen->segment_conv = NULL;
1165}
1166
1167static void
1168destroy_gen(
1169    XLCd lcd)
1170{
1171    XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
1172    destroy_SegConv(gen);
1173    destroy_CodeSetList(gen);
1174    if (gen->mb_parse_table) {
1175	Xfree(gen->mb_parse_table);
1176	gen->mb_parse_table = NULL;
1177    }
1178    if (gen->mb_parse_list) {
1179	Xfree(gen->mb_parse_list);
1180	gen->mb_parse_list = NULL;
1181    }
1182}
1183/* VW/UDC end 95.01.08 */
1184
1185static void
1186destroy(
1187    XLCd lcd)
1188{
1189    XLCdPublicMethods superclass = XLC_PUBLIC_METHODS(lcd)->superclass;
1190
1191    destroy_gen(lcd); /* ADD 1996.01.08 */
1192    if (superclass && superclass->pub.destroy)
1193	(*superclass->pub.destroy)(lcd);
1194}
1195