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