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