lcGeneric.c revision 6cc2b21f
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 = (XLCdPublicMethods) 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);
81    return (XLCd) NULL;
82}
83
84static Bool
85string_to_encoding(
86    const char *str,
87    char *encoding)
88{
89    char *next;
90    long value;
91    int base;
92
93    while (*str) {
94	if (*str == '\\') {
95	    switch (*(str + 1)) {
96		case 'x':
97		case 'X':
98		    base = 16;
99		    break;
100		default:
101		    base = 8;
102		    break;
103	    }
104	    value = strtol(str + 2, &next, base);
105	    if (str + 2 != next) {
106		*((unsigned char *) encoding++) = (unsigned char) value;
107		str = next;
108		continue;
109	    }
110	}
111	*encoding++ = *str++;
112    }
113
114    *encoding = '\0';
115
116    return True;
117}
118
119static Bool
120string_to_ulong(
121    const char *str,
122    unsigned long *value)
123{
124     const char *tmp1 = str;
125     int base;
126
127     if (*tmp1++ != '\\') {
128	  tmp1--;
129	  base = 10;
130     } else {
131	  switch (*tmp1++) {
132	  case 'x':
133	       base = 16;
134	       break;
135	  case 'o':
136	       base = 8;
137	       break;
138	  case 'd':
139	       base = 10;
140	       break;
141	  default:
142	       return(False);
143	  }
144     }
145     *value = (unsigned long) strtol(tmp1, NULL, base);
146     return(True);
147}
148
149
150static Bool
151add_charset(
152    CodeSet codeset,
153    XlcCharSet charset)
154{
155    XlcCharSet *new_list;
156    int num;
157
158    if ((num = codeset->num_charsets))
159        new_list = (XlcCharSet *) Xrealloc(codeset->charset_list,
160                                        (num + 1) * sizeof(XlcCharSet));
161    else
162        new_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet));
163
164    if (new_list == NULL)
165	return False;
166
167    new_list[num] = charset;
168    codeset->charset_list = new_list;
169    codeset->num_charsets = num + 1;
170
171    return True;
172}
173
174static CodeSet
175add_codeset(
176    XLCdGenericPart *gen)
177{
178    CodeSet new, *new_list;
179    int num;
180
181    new = Xcalloc(1, sizeof(CodeSetRec));
182    if (new == NULL)
183        return NULL;
184
185    if ((num = gen->codeset_num))
186        new_list = (CodeSet *) Xrealloc(gen->codeset_list,
187                                        (num + 1) * sizeof(CodeSet));
188    else
189        new_list = (CodeSet *) Xmalloc(sizeof(CodeSet));
190
191    if (new_list == NULL)
192        goto err;
193
194    new_list[num] = new;
195    gen->codeset_list = new_list;
196    gen->codeset_num = num + 1;
197
198    return new;
199
200err:
201    Xfree(new);
202
203    return NULL;
204}
205
206static Bool
207add_parse_list(
208    XLCdGenericPart *gen,
209    EncodingType type,
210    const char *encoding,
211    CodeSet codeset)
212{
213    ParseInfo new, *new_list;
214    char *str;
215    unsigned char ch;
216    int num;
217
218    str = strdup(encoding);
219    if (str == NULL)
220        return False;
221
222    new = Xcalloc(1, sizeof(ParseInfoRec));
223    if (new == NULL)
224        goto err;
225
226    if (gen->mb_parse_table == NULL) {
227        gen->mb_parse_table = Xcalloc(1, 256); /* 2^8 */
228        if (gen->mb_parse_table == NULL)
229            goto err;
230    }
231
232    if ((num = gen->mb_parse_list_num))
233        new_list = (ParseInfo *) Xrealloc(gen->mb_parse_list,
234                                          (num + 2) * sizeof(ParseInfo));
235    else {
236        new_list = (ParseInfo *) Xmalloc(2 * sizeof(ParseInfo));
237    }
238
239    if (new_list == NULL)
240        goto err;
241
242    new_list[num] = new;
243    new_list[num + 1] = NULL;
244    gen->mb_parse_list = new_list;
245    gen->mb_parse_list_num = num + 1;
246
247    ch = (unsigned char) *str;
248    if (gen->mb_parse_table[ch] == 0)
249        gen->mb_parse_table[ch] = num + 1;
250
251    new->type = type;
252    new->encoding = str;
253    new->codeset = codeset;
254
255    if (codeset->parse_info == NULL)
256        codeset->parse_info = new;
257
258    return True;
259
260err:
261    Xfree(str);
262    if (new)
263        Xfree(new);
264
265    return False;
266}
267
268static void
269free_charset(
270    XLCd lcd)
271{
272    XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
273    ParseInfo *parse_info;
274    int num;
275
276    if (gen->mb_parse_table)
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            if ((*parse_info)->encoding)
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 = (FontScope) Xmalloc(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        sprintf(csd, "csd%d", i);
432
433        /* charset_name  */
434        sprintf(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            sprintf(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        sprintf(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        sprintf(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        sprintf(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        sprintf(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 = (char *)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        sprintf(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 = (SegConv) Xrealloc(gen->segment_conv,
540                                        (num + 1) * sizeof(SegConvRec));
541    } else {
542        new_list = (SegConv) 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        sprintf(conv, "conv%d", i);
569
570        /* length                */
571        sprintf(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        sprintf(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        sprintf(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        sprintf(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        sprintf(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    int i,new;
639    FontScope scope;
640    ret = (ExtdSegment)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_name = (char*) Xmalloc (strlen(ret->name) + 1);
649    if (cset_name == NULL) {
650        Xfree (ret->name);
651        Xfree (ret);
652        return NULL;
653    }
654    if (strchr(value[0],':')) {
655        ptr = strchr(ret->name,':');
656        *ptr = '\0';
657        ptr++;
658        if (!_XlcNCompareISOLatin1(ptr, "GL", 2)) {
659            ret->side =  XlcGL;
660            sprintf(cset_name,"%s:%s",ret->name,"GL");
661        } else {
662            ret->side =  XlcGR;
663            sprintf(cset_name,"%s:%s",ret->name,"GR");
664        }
665    } else {
666        ret->side =  XlcGLGR;
667        strcpy(cset_name,ret->name);
668    }
669    ret->area = (FontScope)Xmalloc((num - 1)*sizeof(FontScopeRec));
670    if (ret->area == NULL) {
671	Xfree (cset_name);
672	Xfree (ret->name);
673	Xfree (ret);
674        return NULL;
675    }
676    ret->area_num = num - 1;
677    scope = ret->area ;
678    for (i = 1; i < num; i++) {
679        sscanf(value[i],"\\x%lx,\\x%lx",
680               &scope[i-1].start, &scope[i-1].end);
681    }
682    ret->charset = srch_charset_define(cset_name,&new);
683    Xfree (cset_name);
684
685    return ret;
686}
687/* For VW/UDC end */
688
689static Bool
690load_generic(
691    XLCd lcd)
692{
693    XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
694    char **value;
695    int num;
696    unsigned long l;
697    int i;
698    int M,ii;
699    XlcCharSet charset;
700
701    gen->codeset_num = 0;
702
703    /***** wc_encoding_mask *****/
704    _XlcGetResource(lcd, "XLC_XLOCALE", "wc_encoding_mask", &value, &num);
705    if (num > 0) {
706	if (string_to_ulong(value[0], &l) == False)
707	    goto err;
708	gen->wc_encode_mask = l;
709    }
710    /***** wc_shift_bits *****/
711    _XlcGetResource(lcd, "XLC_XLOCALE", "wc_shift_bits", &value, &num);
712    if (num > 0)
713	gen->wc_shift_bits = atoi(value[0]);
714    if (gen->wc_shift_bits < 1)
715	gen->wc_shift_bits = 8;
716    /***** use_stdc_env *****/
717    _XlcGetResource(lcd, "XLC_XLOCALE", "use_stdc_env", &value, &num);
718    if (num > 0 && !_XlcCompareISOLatin1(value[0], "True"))
719	gen->use_stdc_env = True;
720    else
721	gen->use_stdc_env = False;
722    /***** force_convert_to_mb *****/
723    _XlcGetResource(lcd, "XLC_XLOCALE", "force_convert_to_mb", &value, &num);
724    if (num > 0 && !_XlcCompareISOLatin1(value[0], "True"))
725	gen->force_convert_to_mb = True;
726    else
727	gen->force_convert_to_mb = False;
728
729    for (i = 0; ; i++) {
730	CodeSetRec *codeset = NULL;
731	char cs[16];
732	char name[BUFSIZ];
733
734	sprintf(cs, "cs%d", i);
735
736	/***** codeset.side *****/
737	sprintf(name, "%s.%s", cs , "side");
738	_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
739	if (num > 0) {
740	    char *tmp;
741
742	    if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
743		goto err;
744
745            /* 3.4.1 side */
746            if (!_XlcNCompareISOLatin1(value[0], "none", 4)) {
747                codeset->side =  XlcNONE;
748            } else if (!_XlcNCompareISOLatin1(value[0], "GL", 2)) {
749                codeset->side =  XlcGL;
750            } else {
751                codeset->side =  XlcGR;
752            }
753
754	    tmp = strrchr(value[0], ':');
755	    if (tmp != NULL && !_XlcCompareISOLatin1(tmp + 1, "Default")) {
756		if (codeset->side == XlcGR)
757		    gen->initial_state_GR = codeset;
758		else
759		    gen->initial_state_GL = codeset;
760	    }
761	}
762
763	/***** codeset.length *****/
764	sprintf(name, "%s.%s", cs , "length");
765	_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
766	if (num > 0) {
767	    if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
768		goto err;
769	    codeset->length = atoi(value[0]);
770	    if (codeset->length < 1)
771		codeset->length = 1;
772	}
773
774	/***** codeset.mb_encoding *****/
775	sprintf(name, "%s.%s", cs, "mb_encoding");
776	_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
777	if (num > 0) {
778	    static struct {
779		const char *str;
780		EncodingType type;
781	    } shifts[] = {
782		{"<SS>", E_SS},
783		{"<LSL>", E_LSL},
784		{"<LSR>", E_LSR},
785		{0}
786	    };
787	    int j;
788
789	    if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
790		goto err;
791	    for ( ; num-- > 0; value++) {
792		char encoding[256];
793		char *tmp = *value;
794		EncodingType type = E_SS;    /* for BC */
795		for (j = 0; shifts[j].str; j++) {
796		    if (!_XlcNCompareISOLatin1(tmp, shifts[j].str,
797					       strlen(shifts[j].str))) {
798			type = shifts[j].type;
799			tmp += strlen(shifts[j].str);
800			break;
801		    }
802		}
803		if (strlen (tmp) > sizeof encoding ||
804		    string_to_encoding(tmp, encoding) == False)
805			goto err;
806		add_parse_list(gen, type, encoding, codeset);
807	    }
808	}
809
810	/***** codeset.wc_encoding *****/
811	sprintf(name, "%s.%s", cs, "wc_encoding");
812	_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
813	if (num > 0) {
814	    if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
815		goto err;
816	    if (string_to_ulong(value[0], &l) == False)
817		goto err;
818	    codeset->wc_encoding = l;
819	}
820
821	/***** codeset.ct_encoding *****/
822	sprintf(name, "%s.%s", cs, "ct_encoding");
823	_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
824	if (num > 0) {
825	    char *encoding;
826
827	    if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
828		goto err;
829	    for ( ; num-- > 0; value++) {
830		if (strlen (*value) > sizeof name)
831		    goto err;
832		string_to_encoding(*value, name);
833		charset = NULL;
834		if ((encoding = strchr(name, ':')) &&
835		    (encoding = strchr(encoding + 1, ':'))) {
836		    *encoding++ = '\0';
837		    charset = _XlcAddCT(name, encoding);
838		}
839		if (charset == NULL) {
840		    charset = _XlcGetCharSet(name);
841		    if (charset == NULL &&
842			(charset = _XlcCreateDefaultCharSet(name, ""))) {
843			charset->side = codeset->side;
844			charset->char_size = codeset->length;
845			_XlcAddCharSet(charset);
846		    }
847		}
848		if (charset) {
849		    if (add_charset(codeset, charset) == False)
850			goto err;
851		}
852	    }
853	}
854
855	if (codeset == NULL)
856	    break;
857	codeset->cs_num = i;
858        /* For VW/UDC */
859        /***** 3.4.2 byteM (1 <= M <= length)*****/
860        for (M=1; M-1  < codeset->length; M++) {
861            unsigned long start,end;
862            ByteInfo tmpb;
863
864            sprintf(name,"%s.%s%d",cs,"byte",M);
865            _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
866
867            if (M == 1) {
868                if (num < 1) {
869                    codeset->byteM = NULL;
870                    break ;
871                }
872                codeset->byteM =
873                    (ByteInfoListRec *)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                    (ByteInfo)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        sprintf(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        sprintf(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        sprintf(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        sprintf(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	if (blst[i].byteinfo) {
1032	    Xfree(blst[i].byteinfo);
1033	    blst[i].byteinfo = NULL;
1034	}
1035    }
1036    Xfree(codeset->byteM);
1037    codeset->byteM = NULL;
1038}
1039
1040static void
1041freeConversion(
1042    CodeSet codeset)
1043{
1044    Conversion mbconv,ctconv;
1045    if (codeset->mbconv) {
1046	mbconv = codeset->mbconv;
1047	/*  ...  */
1048	if (mbconv->convlist) {
1049	    Xfree(mbconv->convlist);
1050	    mbconv->convlist = NULL;
1051	}
1052	Xfree(mbconv);
1053	codeset->mbconv = NULL;
1054    }
1055    if (codeset->ctconv) {
1056	ctconv = codeset->ctconv;
1057	/*  ...  */
1058	if (ctconv->convlist) {
1059	    Xfree(ctconv->convlist);
1060	    ctconv->convlist = NULL;
1061	}
1062	Xfree(ctconv);
1063	codeset->ctconv = NULL;
1064    }
1065}
1066
1067static void
1068freeExtdSegment(
1069    CodeSet codeset)
1070{
1071    ExtdSegment ctextseg;
1072    if (codeset->ctextseg == NULL) {
1073	return;
1074    }
1075    ctextseg = codeset->ctextseg;
1076    if (ctextseg->name) {
1077	Xfree(ctextseg->name);
1078	ctextseg->name = NULL;
1079    }
1080    if (ctextseg->area) {
1081	Xfree(ctextseg->area);
1082	ctextseg->area = NULL;
1083    }
1084    Xfree(codeset->ctextseg);
1085    codeset->ctextseg = NULL;
1086}
1087
1088static void
1089freeParseInfo(
1090    CodeSet codeset)
1091{
1092    ParseInfo parse_info;
1093    if (codeset->parse_info == NULL) {
1094	return;
1095    }
1096    parse_info = codeset->parse_info;
1097    if (parse_info->encoding) {
1098	Xfree(parse_info->encoding);
1099	parse_info->encoding = NULL;
1100    }
1101    Xfree(codeset->parse_info);
1102    codeset->parse_info = NULL;
1103}
1104
1105static void
1106destroy_CodeSetList(
1107    XLCdGenericPart *gen)
1108{
1109    CodeSet *codeset = gen->codeset_list;
1110    int i;
1111    if (gen->codeset_num == 0) {
1112	return;
1113    }
1114    for (i=0;i<gen->codeset_num;i++) {
1115        freeByteM(codeset[i]);
1116	freeConversion(codeset[i]);
1117	freeExtdSegment(codeset[i]);
1118	freeParseInfo(codeset[i]);
1119	if (codeset[i]->charset_list) {
1120	    Xfree(codeset[i]->charset_list);
1121	    codeset[i]->charset_list = NULL;
1122	}
1123	Xfree(codeset[i]); codeset[i]=NULL;
1124    }
1125    Xfree(codeset); gen->codeset_list = NULL;
1126}
1127
1128static void
1129destroy_SegConv(
1130    XLCdGenericPart *gen)
1131{
1132    SegConv seg = gen->segment_conv;
1133    int i;
1134    if (gen->segment_conv_num == 0) {
1135	return;
1136    }
1137    for (i=0;i<gen->segment_conv_num;i++) {
1138	if (seg[i].source_encoding) {
1139	    Xfree(seg[i].source_encoding);
1140	    seg[i].source_encoding = NULL;
1141	}
1142	if (seg[i].destination_encoding) {
1143	    Xfree(seg[i].destination_encoding);
1144	    seg[i].destination_encoding = NULL;
1145	}
1146	if (seg[i].conv) {
1147	    Xfree(seg[i].conv); seg[i].conv = NULL;
1148	}
1149    }
1150    Xfree(seg); gen->segment_conv = NULL;
1151}
1152
1153static void
1154destroy_gen(
1155    XLCd lcd)
1156{
1157    XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
1158    destroy_SegConv(gen);
1159    destroy_CodeSetList(gen);
1160    if (gen->mb_parse_table) {
1161	Xfree(gen->mb_parse_table);
1162	gen->mb_parse_table = NULL;
1163    }
1164    if (gen->mb_parse_list) {
1165	Xfree(gen->mb_parse_list);
1166	gen->mb_parse_list = NULL;
1167    }
1168}
1169/* VW/UDC end 95.01.08 */
1170
1171static void
1172destroy(
1173    XLCd lcd)
1174{
1175    XLCdPublicMethods superclass = XLC_PUBLIC_METHODS(lcd)->superclass;
1176
1177    destroy_gen(lcd); /* ADD 1996.01.08 */
1178    if (superclass && superclass->pub.destroy)
1179	(*superclass->pub.destroy)(lcd);
1180}
1181