tizen 2.3 release
[framework/uifw/xorg/lib/libx11.git] / src / xlibi18n / lcGeneric.c
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
38 static XLCd create (const char *name, XLCdMethods methods);
39 static Bool initialize (XLCd lcd);
40 static void destroy (XLCd lcd);
41
42 static XLCdPublicMethodsRec genericMethods = {
43     { NULL },                   /* use default methods */
44     {
45         NULL,
46         create,
47         initialize,
48         destroy,
49         NULL
50     }
51 };
52
53 XLCdMethods _XlcGenericMethods = (XLCdMethods) &genericMethods;
54
55 static XLCd
56 create(
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
79 err:
80     Xfree(lcd);
81     return (XLCd) NULL;
82 }
83
84 static Bool
85 string_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
119 static Bool
120 string_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
150 static Bool
151 add_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
174 static CodeSet
175 add_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
200 err:
201     Xfree(new);
202
203     return NULL;
204 }
205
206 static Bool
207 add_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
260 err:
261     Xfree(str);
262     if (new)
263         Xfree(new);
264
265     return False;
266 }
267
268 static void
269 free_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
296 static const char *
297 getscope(
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
330 static int
331 count_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
344 FontScope
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
365 void
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
378 static void
379 dmpscope(
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
397 static XlcCharSet
398 srch_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
415 static void
416 read_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
531 static SegConv
532 add_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
555 static void
556 read_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
630 static ExtdSegment
631 create_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
689 static Bool
690 load_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
974 err:
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
984 static Bool
985 initialize_core(
986     XLCd lcd)
987 {
988     _XInitDynamicOM(lcd);
989
990     _XInitDynamicIM(lcd);
991
992     return True;
993 }
994 #endif
995
996 static Bool
997 initialize(XLCd lcd)
998 {
999     XLCdPublicMethods superclass = (XLCdPublicMethods) _XlcPublicMethods;
1000
1001     XLC_PUBLIC_METHODS(lcd)->superclass = superclass;
1002
1003 #ifdef _FIX_MEM_LEAK_
1004     //BUGFIX: Memory leak
1005     lcd->methods->close = destroy;
1006 #endif
1007
1008     if (superclass->pub.initialize) {
1009         if ((*superclass->pub.initialize)(lcd) == False)
1010             return False;
1011     }
1012
1013 #ifdef USE_DYNAMIC_LC
1014     if (initialize_core(lcd) == False)
1015         return False;
1016 #endif
1017
1018     if (load_generic(lcd) == False)
1019         return False;
1020
1021     return True;
1022 }
1023
1024 /* VW/UDC start 95.01.08 */
1025 static void
1026 freeByteM(
1027     CodeSet codeset)
1028 {
1029     int i;
1030     ByteInfoList blst;
1031     if (codeset->byteM == NULL) {
1032         return ;
1033     }
1034     blst = codeset->byteM;
1035     for (i = 0; i < codeset->length; i++) {
1036         if (blst[i].byteinfo) {
1037             Xfree(blst[i].byteinfo);
1038             blst[i].byteinfo = NULL;
1039         }
1040     }
1041     Xfree(codeset->byteM);
1042     codeset->byteM = NULL;
1043 }
1044
1045 static void
1046 freeConversion(
1047     CodeSet codeset)
1048 {
1049     Conversion mbconv,ctconv;
1050     if (codeset->mbconv) {
1051         mbconv = codeset->mbconv;
1052         /*  ...  */
1053         if (mbconv->convlist) {
1054             Xfree(mbconv->convlist);
1055             mbconv->convlist = NULL;
1056         }
1057         Xfree(mbconv);
1058         codeset->mbconv = NULL;
1059     }
1060     if (codeset->ctconv) {
1061         ctconv = codeset->ctconv;
1062         /*  ...  */
1063         if (ctconv->convlist) {
1064             Xfree(ctconv->convlist);
1065             ctconv->convlist = NULL;
1066         }
1067         Xfree(ctconv);
1068         codeset->ctconv = NULL;
1069     }
1070 }
1071
1072 static void
1073 freeExtdSegment(
1074     CodeSet codeset)
1075 {
1076     ExtdSegment ctextseg;
1077     if (codeset->ctextseg == NULL) {
1078         return;
1079     }
1080     ctextseg = codeset->ctextseg;
1081     if (ctextseg->name) {
1082         Xfree(ctextseg->name);
1083         ctextseg->name = NULL;
1084     }
1085     if (ctextseg->area) {
1086         Xfree(ctextseg->area);
1087         ctextseg->area = NULL;
1088     }
1089     Xfree(codeset->ctextseg);
1090     codeset->ctextseg = NULL;
1091 }
1092
1093 static void
1094 freeParseInfo(
1095     CodeSet codeset)
1096 {
1097     ParseInfo parse_info;
1098     if (codeset->parse_info == NULL) {
1099         return;
1100     }
1101     parse_info = codeset->parse_info;
1102     if (parse_info->encoding) {
1103         Xfree(parse_info->encoding);
1104         parse_info->encoding = NULL;
1105     }
1106     Xfree(codeset->parse_info);
1107     codeset->parse_info = NULL;
1108 }
1109
1110 static void
1111 destroy_CodeSetList(
1112     XLCdGenericPart *gen)
1113 {
1114     CodeSet *codeset = gen->codeset_list;
1115     int i;
1116     if (gen->codeset_num == 0) {
1117         return;
1118     }
1119     for (i=0;i<gen->codeset_num;i++) {
1120         freeByteM(codeset[i]);
1121         freeConversion(codeset[i]);
1122         freeExtdSegment(codeset[i]);
1123         freeParseInfo(codeset[i]);
1124         if (codeset[i]->charset_list) {
1125             Xfree(codeset[i]->charset_list);
1126             codeset[i]->charset_list = NULL;
1127         }
1128         Xfree(codeset[i]); codeset[i]=NULL;
1129     }
1130     Xfree(codeset); gen->codeset_list = NULL;
1131 }
1132
1133 static void
1134 destroy_SegConv(
1135     XLCdGenericPart *gen)
1136 {
1137     SegConv seg = gen->segment_conv;
1138     int i;
1139     if (gen->segment_conv_num == 0) {
1140         return;
1141     }
1142     for (i=0;i<gen->segment_conv_num;i++) {
1143         if (seg[i].source_encoding) {
1144             Xfree(seg[i].source_encoding);
1145             seg[i].source_encoding = NULL;
1146         }
1147         if (seg[i].destination_encoding) {
1148             Xfree(seg[i].destination_encoding);
1149             seg[i].destination_encoding = NULL;
1150         }
1151         if (seg[i].conv) {
1152             Xfree(seg[i].conv); seg[i].conv = NULL;
1153         }
1154     }
1155     Xfree(seg); gen->segment_conv = NULL;
1156 }
1157
1158 static void
1159 destroy_gen(
1160     XLCd lcd)
1161 {
1162     XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
1163     destroy_SegConv(gen);
1164     destroy_CodeSetList(gen);
1165     if (gen->mb_parse_table) {
1166         Xfree(gen->mb_parse_table);
1167         gen->mb_parse_table = NULL;
1168     }
1169     if (gen->mb_parse_list) {
1170         Xfree(gen->mb_parse_list);
1171         gen->mb_parse_list = NULL;
1172     }
1173 }
1174 /* VW/UDC end 95.01.08 */
1175
1176 static void
1177 destroy(
1178     XLCd lcd)
1179 {
1180     XLCdPublicMethods superclass = XLC_PUBLIC_METHODS(lcd)->superclass;
1181
1182     destroy_gen(lcd); /* ADD 1996.01.08 */
1183     if (superclass && superclass->pub.destroy)
1184         (*superclass->pub.destroy)(lcd);
1185 }