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