1 /***********************************************************************
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 *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
23 * generate <lc.h> implementation tables from lc.tab
24 * this must make it through vanilla cc with no -last
28 * code name ms-codepage
30 * code name alt1|alt2... charset|... attr1|attr2|...
33 * code name lang1|lang2...
51 typedef struct Table_s
57 typedef struct Abbreviation_s
63 typedef struct Attribute_s
68 typedef struct Attribute_list_s
70 struct Attribute_list_s
*next
;
71 Attribute_t
* attribute
;
74 typedef struct Charset_s
81 typedef struct Language_s
87 Attribute_list_t
* attributes
;
90 typedef struct Language_list_s
92 struct Language_list_s
* next
;
96 typedef struct Territory_s
100 Language_list_t
* languages
;
108 Language_t
* language
;
109 Territory_t
* territory
;
111 Attribute_t
* attribute
;
114 static struct State_s
129 #define elementsof(x) (sizeof(x)/sizeof(x[0]))
130 #define newof(p,t,n,x) ((t*)malloc(sizeof(t)*(n)+(x)))
133 #if defined(__STDC__) || defined(__cplusplus)
134 enter(register Table_t
* tab
, register Link_t
* v
)
137 register Table_t
* tab
;
144 for (p
= 0, x
= tab
->root
; x
; p
= x
, x
= x
->next
)
145 if (!strcmp(x
->code
, v
->code
))
152 v
->index
= tab
->count
++;
157 #if defined(__STDC__) || defined(__cplusplus)
158 lookup(register Table_t
* tab
, register char* s
)
161 register Table_t
* tab
;
167 for (x
= tab
->root
; x
; x
= x
->next
)
168 if (!strcmp(x
->code
, s
))
174 #if defined(__STDC__) || defined(__cplusplus)
175 copy(char** p
, register char* f
)
194 #if defined(__STDC__) || defined(__cplusplus)
195 macro(FILE* f
, char* p1
, char* p2
, char* p3
)
224 e
= &buf
[sizeof(buf
)-1];
227 if (!(s
= part
[i
++]))
231 while ((c
= *s
++) && b
< e
)
241 else if (!isalnum(c
))
247 fprintf(f
, "#ifdef %s\n%s,\n#else\n", buf
, buf
);
252 fprintf(f
, "#endif\n");
255 #if defined(__STDC__) || defined(__cplusplus)
257 main(int argc
, char** argv
)
269 Attribute_list_t
* al
;
270 Attribute_list_t
* az
;
288 int language_attribute_max
;
289 int territory_language_max
;
295 if (!(hdr
= *argv
++) || !(lib
= *argv
++) || *argv
)
297 fprintf(stderr
, "%s: { hdr lib tab } arguments expected\n", command
);
300 if (!(hf
= fopen(hdr
, "w")))
302 fprintf(stderr
, "%s: %s: cannot write\n", command
, hdr
);
305 if (!(lf
= fopen(lib
, "w")))
307 fprintf(stderr
, "%s: %s: cannot write\n", command
, lib
);
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");
319 fprintf(hf
, "#ifndef _LC_H\n");
320 fprintf(hf
, "#define _LC_H\t\t\t1\n");
322 fprintf(hf
, "#include <ast.h>\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
);
340 fprintf(lf
, "#include \"lclib.h\"\n");
341 fprintf(lf
, "#include \"lclang.h\"\n");
343 while (s
= fgets(buf
, sizeof(buf
), stdin
))
348 if (!*s
|| *s
== '#')
354 for (*vp
++ = s
; *s
&& !isspace(*s
); s
++);
357 for (*s
++ = 0; isspace(*s
); s
++);
358 if (!strcmp(*(vp
- 1), "-"))
367 if (!strcmp(arg
[0], ":map:"))
369 if (type
!= TERRITORY
)
371 fprintf(stderr
, "%s: %d: %s: must be specified after :territory:\n", command
, line
, arg
[0]);
377 else if (!strcmp(arg
[0], ":charset:"))
381 fprintf(stderr
, "%s: %d: %s must be specified first\n", command
, line
, arg
[0]);
387 else if (!strcmp(arg
[0], ":territory:"))
389 if (type
!= LANGUAGE
)
391 fprintf(stderr
, "%s: %d: %s: must be specified after :language:\n", command
, line
, arg
[0]);
397 else if (!strcmp(arg
[0], ":language:"))
401 fprintf(stderr
, "%s: %d: %s must be specified after :charset:\n", command
, line
, arg
[0]);
409 fprintf(stderr
, "%s: %d: %s invalid\n", command
, line
, arg
[0]);
415 fprintf(stderr
, "%s: %d: at least two arguments expected\n", command
, line
);
421 if (!(cp
= newof(0, Charset_t
, 1, s
- b
+ 1)))
423 fprintf(stderr
, "%s: %d: out of space\n", command
, line
);
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
))
432 fprintf(stderr
, "%s: %d: %s: duplicate charset\n", command
, line
, cp
->link
.code
);
437 if (!(tp
= newof(0, Territory_t
, 1, s
- b
+ 1)))
439 fprintf(stderr
, "%s: %d: out of space\n", command
, line
);
443 tp
->link
.code
= copy(&b
, arg
[0]);
444 tp
->name
= copy(&b
, arg
[1]);
446 if (s
= copy(&b
, arg
[2]))
451 for (; *s
&& *s
!= ':' && *s
!= '|'; s
++);
454 if (!(lp
= (Language_t
*)lookup(&state
.language
, b
)))
456 fprintf(stderr
, "%s: %d: %s: unknown language\n", command
, line
, b
);
459 if (!(ll
= newof(0, Language_list_t
, 1, 0)))
461 fprintf(stderr
, "%s: %d: out of space\n", command
, line
);
474 for (b
= s
; *s
&& *s
!= '|'; s
++);
477 if (!strcmp(b
, "primary"))
481 if (territory_language_max
< i
)
482 territory_language_max
= i
;
484 if (tp
!= (Territory_t
*)enter(&state
.territory
, (Link_t
*)tp
))
486 fprintf(stderr
, "%s: %d: %s: duplicate territory\n", command
, line
, tp
->link
.code
);
491 if (!(lp
= newof(0, Language_t
, 1, s
- b
+ 1)))
493 fprintf(stderr
, "%s: %d: out of space\n", command
, line
);
497 lp
->link
.code
= copy(&b
, arg
[0]);
498 lp
->name
= copy(&b
, arg
[1]);
499 lp
->alternates
= copy(&b
, arg
[2]);
502 else if (!(lp
->charset
= (Charset_t
*)lookup(&state
.charset
, arg
[3])))
504 fprintf(stderr
, "%s: %d: %s: unknown charset\n", command
, line
, arg
[3]);
508 if (s
= copy(&b
, arg
[4]))
511 fprintf(lf
, "\nconst Lc_attribute_t attribute_%s[] =\n{\n", lp
->link
.code
);
514 for (f
= 0; *s
&& *s
!= '|'; s
++)
522 fprintf(lf
, "{\"%s\",", b
);
524 fprintf(lf
, "LC_%s,", f
);
527 if (!(ap
= newof(0, Attribute_t
, 1, 0)))
529 fprintf(stderr
, "%s: %d: out of space\n", command
, line
);
533 ap
->link
.index
= i
++;
534 if (!(al
= newof(0, Attribute_list_t
, 1, 0)))
536 fprintf(stderr
, "%s: %d: out of space\n", command
, line
);
546 macro(lf
, "SUBLANG", lp
->name
, b
);
547 fprintf(lf
, "\n},\n");
549 if (language_attribute_max
< i
)
550 language_attribute_max
= i
;
553 if (lp
!= (Language_t
*)enter(&state
.language
, (Link_t
*)lp
))
555 fprintf(stderr
, "%s: %d: %s: duplicate language\n", command
, line
, lp
->link
.code
);
560 if (!(mp
= newof(0, Map_t
, 1, s
- b
+ 1)))
562 fprintf(stderr
, "%s: %d: out of space\n", command
, line
);
566 mp
->link
.code
= copy(&b
, arg
[0]);
569 fprintf(stderr
, "%s: %d: territory code expected\n", command
, line
);
572 if (!(mp
->language
= (Language_t
*)lookup(&state
.language
, arg
[1])))
574 fprintf(stderr
, "%s: %d: %s: unknown language\n", command
, line
, arg
[1]);
577 if (!(mp
->territory
= (Territory_t
*)lookup(&state
.territory
, arg
[2])))
579 fprintf(stderr
, "%s: %d: %s: unknown territory\n", command
, line
, arg
[2]);
584 else if (!(mp
->charset
= (Charset_t
*)lookup(&state
.charset
, arg
[3])))
586 fprintf(stderr
, "%s: %d: %s: unknown charset\n", command
, line
, arg
[3]);
592 for (al
= mp
->language
->attributes
; al
; al
= al
->next
)
593 if (!strcmp(al
->attribute
->link
.code
, arg
[4]))
595 mp
->attribute
= al
->attribute
;
600 fprintf(stderr
, "%s: %d: %s: unknown attribute\n", command
, line
, arg
[4]);
604 if (mp
!= (Map_t
*)enter(&state
.map
, (Link_t
*)mp
))
606 fprintf(stderr
, "%s: %d: %s: duplicate map\n", command
, line
, mp
->link
.code
);
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");
685 fprintf(hf
, "#if _BLD_ast && defined(__EXPORT__)\n");
686 fprintf(hf
, "#define extern\t\t__EXPORT__\n");
687 fprintf(hf
, "#endif\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");
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
)
700 fprintf(lf
, "{\"%s\",", cp
->link
.code
);
702 fprintf(lf
, "\"%s\",", cp
->alternates
);
706 fprintf(lf
, "\"%s\",", cp
->ms
);
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
++)
717 fprintf(lf
, "{\"debug\",\"debug\",0,&lc_charsets[0],LC_debug,0,");
718 for (i
= 0; i
< language_attribute_max
; i
++)
721 for (lp
= (Language_t
*)state
.language
.root
; lp
; lp
= (Language_t
*)lp
->link
.next
)
723 fprintf(lf
, "{\"%s\",\"%s\",", lp
->link
.code
, lp
->name
);
725 fprintf(lf
, "\"%s\",", lp
->alternates
);
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
++)
734 fprintf(lf
, "\n},\n");
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
++)
742 fprintf(lf
, "{\"debug\",\"debug\",LC_debug,0,&lc_languages[1],");
743 for (i
= 1; i
< 2 * territory_language_max
; i
++)
746 for (tp
= (Territory_t
*)state
.territory
.root
; tp
; tp
= (Territory_t
*)tp
->link
.next
)
748 fprintf(lf
, "{\"%s\",\"%s\",", tp
->link
.code
, tp
->name
);
750 fprintf(lf
, "LC_primary,");
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
++)
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
++)
762 fprintf(lf
, "\n},\n");
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
)
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);
773 fprintf(lf
, "&attribute_%s[%d]", mp
->language
->link
.code
, mp
->attribute
->link
.index
);
778 fprintf(lf
, "\t0\n};\n");
780 fprintf(hf
, "\n#endif\n");