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