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