1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 /*
23 * generate <lc.h> implementation tables from lc.tab
24 * this must make it through vanilla cc with no -last
25 *
26 * # comment
27 * :charset:
28 * code name ms-codepage
29 * :language:
30 * code name alt1|alt2... charset|... attr1|attr2|...
31 * ...
32 * :territory:
33 * code name lang1|lang2...
34 * :abbreviation:
35 */
36
37 #include <stdio.h>
38 #include <ctype.h>
39 #ifdef __STDC__
40 #include <stdlib.h>
41 #include <string.h>
42 #endif
43
44 typedef struct Link_s
45 {
46 struct Link_s* next;
47 char* code;
48 int index;
49 } Link_t;
50
51 typedef struct Table_s
52 {
53 Link_t* root;
54 int count;
55 } Table_t;
56
57 typedef struct Abbreviation_s
58 {
59 Link_t link;
60 char* value;
61 } Abbreviation_t;
62
63 typedef struct Attribute_s
64 {
65 Link_t link;
66 } Attribute_t;
67
68 typedef struct Attribute_list_s
69 {
70 struct Attribute_list_s*next;
71 Attribute_t* attribute;
72 } Attribute_list_t;
73
74 typedef struct Charset_s
75 {
76 Link_t link;
77 char* alternates;
78 char* ms;
79 } Charset_t;
80
81 typedef struct Language_s
82 {
83 Link_t link;
84 char* name;
85 char* alternates;
86 Charset_t* charset;
87 Attribute_list_t* attributes;
88 } Language_t;
89
90 typedef struct Language_list_s
91 {
92 struct Language_list_s* next;
93 Language_t* language;
94 } Language_list_t;
95
96 typedef struct Territory_s
97 {
98 Link_t link;
99 char* name;
100 Language_list_t* languages;
101 int primary;
102 int index;
103 } Territory_t;
104
105 typedef struct Map_s
106 {
107 Link_t link;
108 Language_t* language;
109 Territory_t* territory;
110 Charset_t* charset;
111 Attribute_t* attribute;
112 } Map_t;
113
114 static struct State_s
115 {
116 Table_t attribute;
117 Table_t charset;
118 Table_t language;
119 Table_t territory;
120 Table_t map;
121 } state;
122
123 #define INIT 0
124 #define CHARSET 1
125 #define LANGUAGE 2
126 #define TERRITORY 3
127 #define MAP 4
128
129 #define elementsof(x) (sizeof(x)/sizeof(x[0]))
130 #define newof(p,t,n,x) ((t*)malloc(sizeof(t)*(n)+(x)))
131
132 static Link_t*
133 #if defined(__STDC__) || defined(__cplusplus)
enter(register Table_t * tab,register Link_t * v)134 enter(register Table_t* tab, register Link_t* v)
135 #else
136 enter(tab, v)
137 register Table_t* tab;
138 register Link_t* v;
139 #endif
140 {
141 register Link_t* x;
142 register Link_t* p;
143
144 for (p = 0, x = tab->root; x; p = x, x = x->next)
145 if (!strcmp(x->code, v->code))
146 return x;
147 if (p)
148 p->next = v;
149 else
150 tab->root = v;
151 v->next = 0;
152 v->index = tab->count++;
153 return v;
154 }
155
156 static Link_t*
157 #if defined(__STDC__) || defined(__cplusplus)
lookup(register Table_t * tab,register char * s)158 lookup(register Table_t* tab, register char* s)
159 #else
160 lookup(tab, s)
161 register Table_t* tab;
162 register char* s;
163 #endif
164 {
165 register Link_t* x;
166
167 for (x = tab->root; x; x = x->next)
168 if (!strcmp(x->code, s))
169 return x;
170 return 0;
171 }
172
173 static char*
174 #if defined(__STDC__) || defined(__cplusplus)
copy(char ** p,register char * f)175 copy(char** p, register char* f)
176 #else
177 copy(p, f)
178 char** p;
179 register char* f;
180 #endif
181 {
182 register char* t;
183 char* b;
184
185 if (!f)
186 return 0;
187 b = t = *p;
188 while (*t++ = *f++);
189 *p = t;
190 return b;
191 }
192
193 static void
194 #if defined(__STDC__) || defined(__cplusplus)
macro(FILE * f,char * p1,char * p2,char * p3)195 macro(FILE* f, char* p1, char* p2, char* p3)
196 #else
197 macro(f, p1, p2, p3)
198 FILE* f;
199 char* p1;
200 char* p2;
201 char* p3;
202 #endif
203 {
204 register int c;
205 register char* s;
206 register char* b;
207 register char* e;
208 int i;
209 int m;
210 int n;
211 char* part[4];
212 char buf[128];
213
214 part[0] = p1;
215 part[1] = p2;
216 part[2] = p3;
217 part[3] = 0;
218 n = 0;
219 fprintf(f, "\n");
220 do
221 {
222 i = m = 0;
223 b = buf;
224 e = &buf[sizeof(buf)-1];
225 while (b < e)
226 {
227 if (!(s = part[i++]))
228 break;
229 if (i > 1)
230 *b++ = '_';
231 while ((c = *s++) && b < e)
232 {
233 if (c == '|')
234 {
235 part[i-1] = s;
236 m = 1;
237 break;
238 }
239 else if (islower(c))
240 c = toupper(c);
241 else if (!isalnum(c))
242 c = '_';
243 *b++ = c;
244 }
245 }
246 *b = 0;
247 fprintf(f, "#ifdef %s\n%s,\n#else\n", buf, buf);
248 n++;
249 } while (m);
250 fprintf(f, "0,\n");
251 while (n-- > 0)
252 fprintf(f, "#endif\n");
253 }
254
255 #if defined(__STDC__) || defined(__cplusplus)
256 int
main(int argc,char ** argv)257 main(int argc, char** argv)
258 #else
259 int
260 main(argc, argv)
261 int argc;
262 char** argv;
263 #endif
264 {
265 register char* s;
266 register char** vp;
267 register char** ve;
268 Attribute_t* ap;
269 Attribute_list_t* al;
270 Attribute_list_t* az;
271 Charset_t* cp;
272 Territory_t* tp;
273 Language_t* lp;
274 Language_list_t* ll;
275 Language_list_t* lz;
276 Map_t* mp;
277 char* b;
278 char* f;
279 char* command;
280 char* hdr;
281 char* lib;
282 FILE* hf;
283 FILE* lf;
284 int c;
285 int i;
286 int line;
287 int type;
288 int language_attribute_max;
289 int territory_language_max;
290 char* arg[5];
291 char buf[1024];
292
293 command = *argv++;
294 line = 0;
295 if (!(hdr = *argv++) || !(lib = *argv++) || *argv)
296 {
297 fprintf(stderr, "%s: { hdr lib tab } arguments expected\n", command);
298 return 1;
299 }
300 if (!(hf = fopen(hdr, "w")))
301 {
302 fprintf(stderr, "%s: %s: cannot write\n", command, hdr);
303 return 1;
304 }
305 if (!(lf = fopen(lib, "w")))
306 {
307 fprintf(stderr, "%s: %s: cannot write\n", command, lib);
308 return 1;
309 }
310 type = 0;
311 language_attribute_max = 0;
312 territory_language_max = 0;
313 state.language.count = 2;
314 state.territory.count = 2;
315 ve = &arg[elementsof(arg)];
316 fprintf(hf, "/* : : generated by %s : : */\n", command);
317 fprintf(hf, "#pragma prototyped\n");
318 fprintf(hf, "\n");
319 fprintf(hf, "#ifndef _LC_H\n");
320 fprintf(hf, "#define _LC_H\t\t\t1\n");
321 fprintf(hf, "\n");
322 fprintf(hf, "#include <ast.h>\n");
323 fprintf(hf, "\n");
324 fprintf(hf, "#define LC_abbreviated\t\t0x00001\n");
325 fprintf(hf, "#define LC_checked\t\t0x00002\n");
326 fprintf(hf, "#define LC_debug\t\t0x00004\n");
327 fprintf(hf, "#define LC_default\t\t0x00008\n");
328 fprintf(hf, "#define LC_defined\t\t0x00010\n");
329 fprintf(hf, "#define LC_local\t\t0x00020\n");
330 fprintf(hf, "#define LC_primary\t\t0x00040\n");
331 fprintf(hf, "#define LC_qualified\t\t0x00080\n");
332 fprintf(hf, "#define LC_undefined\t\t0x00100\n");
333 fprintf(hf, "#define LC_utf8\t\t\t0x00200\n");
334 fprintf(hf, "#define LC_verbose\t\t0x00400\n");
335 fprintf(hf, "#define LC_setlocale\t\t\t0x10000\n");
336 fprintf(hf, "#define LC_setenv\t\t\t0x20000\n");
337 fprintf(hf, "#define LC_user\t\t\t0x40000\n");
338 fprintf(lf, "/* : : generated by %s : : */\n", command);
339 fprintf(lf, "\n");
340 fprintf(lf, "#include \"lclib.h\"\n");
341 fprintf(lf, "#include \"lclang.h\"\n");
342 fprintf(lf, "\n");
343 while (s = fgets(buf, sizeof(buf), stdin))
344 {
345 line++;
346 while (isspace(*s))
347 s++;
348 if (!*s || *s == '#')
349 continue;
350 b = s;
351 vp = arg;
352 for (;;)
353 {
354 for (*vp++ = s; *s && !isspace(*s); s++);
355 if (!*s)
356 break;
357 for (*s++ = 0; isspace(*s); s++);
358 if (!strcmp(*(vp - 1), "-"))
359 *(vp - 1) = 0;
360 if (!*s || vp >= ve)
361 break;
362 }
363 while (vp < ve)
364 *vp++ = 0;
365 if (*arg[0] == ':')
366 {
367 if (!strcmp(arg[0], ":map:"))
368 {
369 if (type != TERRITORY)
370 {
371 fprintf(stderr, "%s: %d: %s: must be specified after :territory:\n", command, line, arg[0]);
372 return 1;
373 }
374 type = MAP;
375 continue;
376 }
377 else if (!strcmp(arg[0], ":charset:"))
378 {
379 if (type != INIT)
380 {
381 fprintf(stderr, "%s: %d: %s must be specified first\n", command, line, arg[0]);
382 return 1;
383 }
384 type = CHARSET;
385 continue;
386 }
387 else if (!strcmp(arg[0], ":territory:"))
388 {
389 if (type != LANGUAGE)
390 {
391 fprintf(stderr, "%s: %d: %s: must be specified after :language:\n", command, line, arg[0]);
392 return 1;
393 }
394 type = TERRITORY;
395 continue;
396 }
397 else if (!strcmp(arg[0], ":language:"))
398 {
399 if (type != CHARSET)
400 {
401 fprintf(stderr, "%s: %d: %s must be specified after :charset:\n", command, line, arg[0]);
402 return 1;
403 }
404 type = LANGUAGE;
405 continue;
406 }
407 else
408 {
409 fprintf(stderr, "%s: %d: %s invalid\n", command, line, arg[0]);
410 return 1;
411 }
412 }
413 if (!arg[1])
414 {
415 fprintf(stderr, "%s: %d: at least two arguments expected\n", command, line);
416 return 1;
417 }
418 switch (type)
419 {
420 case CHARSET:
421 if (!(cp = newof(0, Charset_t, 1, s - b + 1)))
422 {
423 fprintf(stderr, "%s: %d: out of space\n", command, line);
424 return 1;
425 }
426 b = (char*)(cp + 1);
427 cp->link.code = copy(&b, arg[0]);
428 cp->alternates = copy(&b, arg[1]);
429 cp->ms = copy(&b, arg[2]);
430 if (cp != (Charset_t*)enter(&state.charset, (Link_t*)cp))
431 {
432 fprintf(stderr, "%s: %d: %s: duplicate charset\n", command, line, cp->link.code);
433 return 1;
434 }
435 break;
436 case TERRITORY:
437 if (!(tp = newof(0, Territory_t, 1, s - b + 1)))
438 {
439 fprintf(stderr, "%s: %d: out of space\n", command, line);
440 return 1;
441 }
442 b = (char*)(tp + 1);
443 tp->link.code = copy(&b, arg[0]);
444 tp->name = copy(&b, arg[1]);
445 tp->languages = 0;
446 if (s = copy(&b, arg[2]))
447 {
448 i = 0;
449 while (*(b = s))
450 {
451 for (; *s && *s != ':' && *s != '|'; s++);
452 if (c = *s)
453 *s++ = 0;
454 if (!(lp = (Language_t*)lookup(&state.language, b)))
455 {
456 fprintf(stderr, "%s: %d: %s: unknown language\n", command, line, b);
457 return 1;
458 }
459 if (!(ll = newof(0, Language_list_t, 1, 0)))
460 {
461 fprintf(stderr, "%s: %d: out of space\n", command, line);
462 return 1;
463 }
464 if (!tp->languages)
465 tp->languages = ll;
466 else
467 lz->next = ll;
468 lz = ll;
469 ll->language = lp;
470 ll->next = 0;
471 i++;
472 if (c == ':')
473 {
474 for (b = s; *s && *s != '|'; s++);
475 if (*s)
476 *s++ = 0;
477 if (!strcmp(b, "primary"))
478 tp->primary = 1;
479 }
480 }
481 if (territory_language_max < i)
482 territory_language_max = i;
483 }
484 if (tp != (Territory_t*)enter(&state.territory, (Link_t*)tp))
485 {
486 fprintf(stderr, "%s: %d: %s: duplicate territory\n", command, line, tp->link.code);
487 return 1;
488 }
489 break;
490 case LANGUAGE:
491 if (!(lp = newof(0, Language_t, 1, s - b + 1)))
492 {
493 fprintf(stderr, "%s: %d: out of space\n", command, line);
494 return 1;
495 }
496 b = (char*)(lp + 1);
497 lp->link.code = copy(&b, arg[0]);
498 lp->name = copy(&b, arg[1]);
499 lp->alternates = copy(&b, arg[2]);
500 if (!arg[3])
501 lp->charset = 0;
502 else if (!(lp->charset = (Charset_t*)lookup(&state.charset, arg[3])))
503 {
504 fprintf(stderr, "%s: %d: %s: unknown charset\n", command, line, arg[3]);
505 return 1;
506 }
507 lp->attributes = 0;
508 if (s = copy(&b, arg[4]))
509 {
510 i = 0;
511 fprintf(lf, "\nconst Lc_attribute_t attribute_%s[] =\n{\n", lp->link.code);
512 while (*(b = s))
513 {
514 for (f = 0; *s && *s != '|'; s++)
515 if (*s == ':')
516 {
517 *s++ = 0;
518 f = s;
519 }
520 if (*s)
521 *s++ = 0;
522 fprintf(lf, "{\"%s\",", b);
523 if (f)
524 fprintf(lf, "LC_%s,", f);
525 else
526 fprintf(lf, "0,");
527 if (!(ap = newof(0, Attribute_t, 1, 0)))
528 {
529 fprintf(stderr, "%s: %d: out of space\n", command, line);
530 return 1;
531 }
532 ap->link.code = b;
533 ap->link.index = i++;
534 if (!(al = newof(0, Attribute_list_t, 1, 0)))
535 {
536 fprintf(stderr, "%s: %d: out of space\n", command, line);
537 return 1;
538 }
539 if (!lp->attributes)
540 lp->attributes = al;
541 else
542 az->next = al;
543 az = al;
544 al->attribute = ap;
545 al->next = 0;
546 macro(lf, "SUBLANG", lp->name, b);
547 fprintf(lf, "\n},\n");
548 }
549 if (language_attribute_max < i)
550 language_attribute_max = i;
551 fprintf(lf, "};\n");
552 }
553 if (lp != (Language_t*)enter(&state.language, (Link_t*)lp))
554 {
555 fprintf(stderr, "%s: %d: %s: duplicate language\n", command, line, lp->link.code);
556 return 1;
557 }
558 break;
559 case MAP:
560 if (!(mp = newof(0, Map_t, 1, s - b + 1)))
561 {
562 fprintf(stderr, "%s: %d: out of space\n", command, line);
563 return 1;
564 }
565 b = (char*)(mp + 1);
566 mp->link.code = copy(&b, arg[0]);
567 if (!arg[2])
568 {
569 fprintf(stderr, "%s: %d: territory code expected\n", command, line);
570 return 1;
571 }
572 if (!(mp->language = (Language_t*)lookup(&state.language, arg[1])))
573 {
574 fprintf(stderr, "%s: %d: %s: unknown language\n", command, line, arg[1]);
575 return 1;
576 }
577 if (!(mp->territory = (Territory_t*)lookup(&state.territory, arg[2])))
578 {
579 fprintf(stderr, "%s: %d: %s: unknown territory\n", command, line, arg[2]);
580 return 1;
581 }
582 if (!arg[3])
583 mp->charset = 0;
584 else if (!(mp->charset = (Charset_t*)lookup(&state.charset, arg[3])))
585 {
586 fprintf(stderr, "%s: %d: %s: unknown charset\n", command, line, arg[3]);
587 return 1;
588 }
589 mp->attribute = 0;
590 if (arg[4])
591 {
592 for (al = mp->language->attributes; al; al = al->next)
593 if (!strcmp(al->attribute->link.code, arg[4]))
594 {
595 mp->attribute = al->attribute;
596 break;
597 }
598 if (!mp->attribute)
599 {
600 fprintf(stderr, "%s: %d: %s: unknown attribute\n", command, line, arg[4]);
601 return 1;
602 }
603 }
604 if (mp != (Map_t*)enter(&state.map, (Link_t*)mp))
605 {
606 fprintf(stderr, "%s: %d: %s: duplicate map\n", command, line, mp->link.code);
607 return 1;
608 }
609 break;
610 }
611 }
612 fprintf(hf, "#define LC_language_attribute_max\t\t%d\n", language_attribute_max);
613 fprintf(hf, "#define LC_territory_language_max\t\t%d\n", territory_language_max);
614 fprintf(hf, "\nstruct Lc_s;\n");
615 fprintf(hf, "\ntypedef struct Lc_info_s\n{\n");
616 fprintf(hf, "\tconst struct Lc_s*\tlc;\n");
617 fprintf(hf, "\tunsigned long\t\tnumber;\n");
618 fprintf(hf, "\tvoid*\t\t\tdata;\n");
619 fprintf(hf, "} Lc_info_t;\n");
620 fprintf(hf, "\ntypedef struct Lc_attribute_s\n{\n");
621 fprintf(hf, "\tconst char*\t\tname;\n");
622 fprintf(hf, "\tunsigned long\t\tflags;\n");
623 fprintf(hf, "\tunsigned long\t\tindex;\n");
624 fprintf(hf, "} Lc_attribute_t;\n");
625 fprintf(hf, "\ntypedef struct Lc_charset_s\n{\n");
626 fprintf(hf, "\tconst char*\t\tcode;\n");
627 fprintf(hf, "\tconst char*\t\talternates;\n");
628 fprintf(hf, "\tconst char*\t\tms;\n");
629 fprintf(hf, "\tunsigned long\t\tindex;\n");
630 fprintf(hf, "} Lc_charset_t;\n");
631 fprintf(hf, "\ntypedef struct Lc_language_s\n{\n");
632 fprintf(hf, "\tconst char*\t\tcode;\n");
633 fprintf(hf, "\tconst char*\t\tname;\n");
634 fprintf(hf, "\tconst char*\t\talternates;\n");
635 fprintf(hf, "\tconst Lc_charset_t*\tcharset;\n");
636 fprintf(hf, "\tunsigned long\t\tflags;\n");
637 fprintf(hf, "\tunsigned long\t\tindex;\n");
638 fprintf(hf, "\tconst Lc_attribute_t*\tattributes[LC_language_attribute_max];\n");
639 fprintf(hf, "} Lc_language_t;\n");
640 fprintf(hf, "\ntypedef struct Lc_territory_s\n{\n");
641 fprintf(hf, "\tconst char*\t\tcode;\n");
642 fprintf(hf, "\tconst char*\t\tname;\n");
643 fprintf(hf, "\tunsigned long\t\tflags;\n");
644 fprintf(hf, "\tunsigned long\t\tindex;\n");
645 fprintf(hf, "\tconst Lc_language_t*\tlanguages[LC_territory_language_max];\n");
646 fprintf(hf, "#ifdef _LC_TERRITORY_PRIVATE_\n");
647 fprintf(hf, "\t_LC_TERRITORY_PRIVATE_\n");
648 fprintf(hf, "#endif\n");
649 fprintf(hf, "} Lc_territory_t;\n");
650 fprintf(hf, "\ntypedef struct Lc_map_s\n{\n");
651 fprintf(hf, "\tconst char*\t\tcode;\n");
652 fprintf(hf, "\tconst Lc_language_t*\tlanguage;\n");
653 fprintf(hf, "\tconst Lc_territory_t*\tterritory;\n");
654 fprintf(hf, "\tconst Lc_charset_t*\tcharset;\n");
655 fprintf(hf, "\tconst Lc_attribute_t*\tattribute;\n");
656 fprintf(hf, "} Lc_map_t;\n");
657 fprintf(hf, "\ntypedef struct Lc_attribute_list_s\n{\n");
658 fprintf(hf, "\tstruct Lc_attribute_list_s*\tnext;\n");
659 fprintf(hf, "\tconst Lc_attribute_t*\t\tattribute;\n");
660 fprintf(hf, "} Lc_attribute_list_t;\n");
661 fprintf(hf, "\ntypedef struct Lc_s\n{\n");
662 fprintf(hf, "\tconst char*\t\tname;\n");
663 fprintf(hf, "\tconst char*\t\tcode;\n");
664 fprintf(hf, "\tconst Lc_language_t*\tlanguage;\n");
665 fprintf(hf, "\tconst Lc_territory_t*\tterritory;\n");
666 fprintf(hf, "\tconst Lc_charset_t*\tcharset;\n");
667 fprintf(hf, "\tconst Lc_attribute_list_t*\tattributes;\n");
668 fprintf(hf, "\tunsigned long\t\tflags;\n");
669 fprintf(hf, "\tunsigned long\t\tindex;\n");
670 fprintf(hf, "#ifdef _LC_PRIVATE_\n");
671 fprintf(hf, "\t_LC_PRIVATE_\n");
672 fprintf(hf, "#endif\n");
673 fprintf(hf, "} Lc_t;\n");
674 fprintf(hf, "\nstruct Lc_category_s;\n");
675 fprintf(hf, "\ntypedef int (*Lc_category_set_f)(struct Lc_category_s*);\n");
676 fprintf(hf, "\ntypedef struct Lc_category_s\n{\n");
677 fprintf(hf, "\tconst char*\t\tname;\n");
678 fprintf(hf, "\tint\t\t\texternal;\n");
679 fprintf(hf, "\tint\t\t\tinternal;\n");
680 fprintf(hf, "\tLc_category_set_f\tsetf;\n");
681 fprintf(hf, "\tLc_t*\t\t\tprev;\n");
682 fprintf(hf, "\tunsigned int\t\tflags;\n");
683 fprintf(hf, "} Lc_category_t;\n");
684 fprintf(hf, "\n");
685 fprintf(hf, "#if _BLD_ast && defined(__EXPORT__)\n");
686 fprintf(hf, "#define extern\t\t__EXPORT__\n");
687 fprintf(hf, "#endif\n");
688 fprintf(hf, "\n");
689 fprintf(hf, "extern size_t\t\tlccanon(Lc_t*, unsigned long flags, char*, size_t);\n");
690 fprintf(hf, "extern Lc_category_t*\tlccategories(void);\n");
691 fprintf(hf, "extern int\t\tlcindex(int, int);\n");
692 fprintf(hf, "extern Lc_info_t*\tlcinfo(int);\n");
693 fprintf(hf, "extern Lc_t*\t\tlcmake(const char*);\n");
694 fprintf(hf, "extern Lc_t*\t\tlcscan(Lc_t*);\n");
695 fprintf(hf, "\n");
696 fprintf(hf, "#undef\textern\n");
697 fprintf(lf, "\nconst Lc_charset_t lc_charsets[] =\n{\n");
698 for (cp = (Charset_t*)state.charset.root; cp; cp = (Charset_t*)cp->link.next)
699 {
700 fprintf(lf, "{\"%s\",", cp->link.code);
701 if (cp->alternates)
702 fprintf(lf, "\"%s\",", cp->alternates);
703 else
704 fprintf(lf, "0,");
705 if (cp->ms)
706 fprintf(lf, "\"%s\",", cp->ms);
707 else
708 fprintf(lf, "0");
709 fprintf(lf, "},\n");
710 }
711 fprintf(lf, "\t0\n};\n");
712 fprintf(lf, "\nconst Lc_language_t lc_languages[] =\n{\n");
713 fprintf(lf, "{\"C\",\"C\",\"POSIX\",&lc_charsets[0],LC_default,0,");
714 for (i = 0; i < language_attribute_max; i++)
715 fprintf(lf, "0,");
716 fprintf(lf, "},\n");
717 fprintf(lf, "{\"debug\",\"debug\",0,&lc_charsets[0],LC_debug,0,");
718 for (i = 0; i < language_attribute_max; i++)
719 fprintf(lf, "0,");
720 fprintf(lf, "},\n");
721 for (lp = (Language_t*)state.language.root; lp; lp = (Language_t*)lp->link.next)
722 {
723 fprintf(lf, "{\"%s\",\"%s\",", lp->link.code, lp->name);
724 if (lp->alternates)
725 fprintf(lf, "\"%s\",", lp->alternates);
726 else
727 fprintf(lf, "0,");
728 fprintf(lf, "&lc_charsets[%d],0,", lp->charset ? lp->charset->link.index : 0);
729 macro(lf, "LANG", lp->name, (char*)0);
730 for (i = 0, al = lp->attributes; al; al = al->next, i++)
731 fprintf(lf, "&attribute_%s[%d],", lp->link.code, al->attribute->link.index);
732 for (; i < language_attribute_max; i++)
733 fprintf(lf, "0,");
734 fprintf(lf, "\n},\n");
735 }
736 fprintf(lf, "\t0\n};\n");
737 fprintf(lf, "\nconst Lc_territory_t lc_territories[] =\n{\n");
738 fprintf(lf, "{\"C\",\"C\",LC_default,0,&lc_languages[0],");
739 for (i = 1; i < 2 * territory_language_max; i++)
740 fprintf(lf, "0,");
741 fprintf(lf, "},\n");
742 fprintf(lf, "{\"debug\",\"debug\",LC_debug,0,&lc_languages[1],");
743 for (i = 1; i < 2 * territory_language_max; i++)
744 fprintf(lf, "0,");
745 fprintf(lf, "},\n");
746 for (tp = (Territory_t*)state.territory.root; tp; tp = (Territory_t*)tp->link.next)
747 {
748 fprintf(lf, "{\"%s\",\"%s\",", tp->link.code, tp->name);
749 if (tp->primary)
750 fprintf(lf, "LC_primary,");
751 else
752 fprintf(lf, "0,");
753 macro(lf, "CTRY", tp->name, (char*)0);
754 for (i = 0, ll = tp->languages; ll; ll = ll->next, i++)
755 fprintf(lf, "&lc_languages[%d],", ll->language->link.index);
756 for (; i < territory_language_max; i++)
757 fprintf(lf, "0,");
758 for (i = 0, ll = tp->languages; ll; ll = ll->next, i++)
759 macro(lf, "SUBLANG", ll->language->name, tp->name);
760 for (; i < territory_language_max; i++)
761 fprintf(lf, "0,");
762 fprintf(lf, "\n},\n");
763 }
764 fprintf(lf, "\t0\n};\n");
765 fprintf(lf, "\nconst Lc_map_t lc_maps[] =\n{\n");
766 for (mp = (Map_t*)state.map.root; mp; mp = (Map_t*)mp->link.next)
767 {
768 fprintf(lf, "{\"%s\",", mp->link.code);
769 fprintf(lf, "&lc_languages[%d],", mp->language->link.index);
770 fprintf(lf, "&lc_territories[%d],", mp->territory->link.index);
771 fprintf(lf, "&lc_charsets[%d],", mp->charset ? mp->charset->link.index : 0);
772 if (mp->attribute)
773 fprintf(lf, "&attribute_%s[%d]", mp->language->link.code, mp->attribute->link.index);
774 else
775 fprintf(lf, "0");
776 fprintf(lf, "},\n");
777 }
778 fprintf(lf, "\t0\n};\n");
779 fclose(lf);
780 fprintf(hf, "\n#endif\n");
781 fclose(hf);
782 return 0;
783 }
784