4 * The Regents of the University of California. All rights reserved.
6 * This code is derived from software contributed to Berkeley by
7 * Paul Borman at Krystal Technologies.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 static char sccsid
[] = "@(#)yacc.y 8.1 (Berkeley) 6/6/93";
40 #include <sys/cdefs.h>
41 __FBSDID
("$FreeBSD$");
43 #include <arpa/inet.h>
57 static void *xmalloc
(unsigned int sz
);
58 static uint32_t *xlalloc
(unsigned int sz
);
59 void yyerror(const char *s
);
60 static uint32_t *xrelalloc
(uint32_t *old
, unsigned int sz
);
61 static void dump_tables
(void);
62 static void cleanout
(void);
64 const char *locale_file
= "<stdout>";
66 rune_map maplower
= { { 0 }, NULL
};
67 rune_map mapupper
= { { 0 }, NULL
};
68 rune_map types
= { { 0 }, NULL
};
70 _FileRuneLocale new_locale
= { "", "", {}, {}, {}, 0, 0, 0, 0 };
71 char *variable
= NULL
;
73 void set_map
(rune_map
*, rune_list
*, uint32_t);
74 void set_digitmap
(rune_map
*, rune_list
*);
75 void add_map
(rune_map
*, rune_list
*, uint32_t);
76 static void usage
(void);
115 entry
: ENCODING STRING
116 { if
(strcmp
($2, "NONE") &&
117 strcmp
($2, "ASCII") &&
118 strcmp
($2, "UTF-8") &&
121 strcmp
($2, "GB18030") &&
122 strcmp
($2, "GB2312") &&
123 strcmp
($2, "BIG5") &&
124 strcmp
($2, "MSKanji"))
125 warnx
("ENCODING %s is not supported by libc", $2);
126 strlcpy
(new_locale.encoding
, $2,
127 sizeof
(new_locale.encoding
)); }
129 { new_locale.variable_len
= strlen
($1) + 1;
130 variable
= xmalloc
(new_locale.variable_len
);
131 strcpy
(variable
, $1);
134 { warnx
("the INVALID keyword is deprecated"); }
136 { set_map
(&types
, $2, $1); }
138 { set_map
(&maplower
, $2, 0); }
140 { set_map
(&mapupper
, $2, 0); }
142 { set_digitmap
(&types
, $2); }
147 $$
= (rune_list
*)xmalloc
(sizeof
(rune_list
));
154 $$
= (rune_list
*)xmalloc
(sizeof
(rune_list
));
161 $$
= (rune_list
*)xmalloc
(sizeof
(rune_list
));
166 | list RUNE THRU RUNE
168 $$
= (rune_list
*)xmalloc
(sizeof
(rune_list
));
175 map
: LBRK RUNE RUNE RBRK
177 $$
= (rune_list
*)xmalloc
(sizeof
(rune_list
));
183 | map LBRK RUNE RUNE RBRK
185 $$
= (rune_list
*)xmalloc
(sizeof
(rune_list
));
191 | LBRK RUNE THRU RUNE
':' RUNE RBRK
193 $$
= (rune_list
*)xmalloc
(sizeof
(rune_list
));
199 | map LBRK RUNE THRU RUNE
':' RUNE RBRK
201 $$
= (rune_list
*)xmalloc
(sizeof
(rune_list
));
221 main
(int ac
, char *av
[])
227 while
((x
= getopt
(ac
, av
, "do:")) != -1) {
233 locale_file
= optarg
;
234 if
((fp
= fopen
(locale_file
, "w")) == NULL
)
235 err
(1, "%s", locale_file
);
243 switch
(ac
- optind
) {
247 if
(freopen
(av
[optind
], "r", stdin
) == 0)
248 err
(1, "%s", av
[optind
]);
253 for
(x
= 0; x
< _CACHED_RUNES
; ++x
) {
257 memcpy
(new_locale.magic
, _FILE_RUNE_MAGIC_1
, sizeof
(new_locale.magic
));
267 fprintf
(stderr
, "usage: mklocale [-d] [-o output] [source]\n");
272 yyerror(const char *s
)
274 fprintf
(stderr
, "%s\n", s
);
278 xmalloc
(unsigned int sz
)
280 void *r
= malloc
(sz
);
287 xlalloc
(unsigned int sz
)
289 uint32_t *r
= (uint32_t *)malloc
(sz
* sizeof
(uint32_t));
296 xrelalloc
(uint32_t *old
, unsigned int sz
)
298 uint32_t *r
= (uint32_t *)realloc
((char *)old
,
299 sz
* sizeof
(uint32_t));
301 errx
(1, "xrelalloc");
306 set_map
(rune_map
*map
, rune_list
*list
, uint32_t flag
)
309 rune_list
*nlist
= list
->next
;
310 add_map
(map
, list
, flag
);
316 set_digitmap
(rune_map
*map
, rune_list
*list
)
321 rune_list
*nlist
= list
->next
;
322 for
(i
= list
->min
; i
<= list
->max
; ++i
) {
323 if
(list
->map
+ (i
- list
->min
)) {
324 rune_list
*tmp
= (rune_list
*)xmalloc
(sizeof
(rune_list
));
327 add_map
(map
, tmp
, list
->map
+ (i
- list
->min
));
336 add_map
(rune_map
*map
, rune_list
*list
, uint32_t flag
)
343 while
(list
->min
< _CACHED_RUNES
&& list
->min
<= list
->max
) {
345 map
->map
[list
->min
++] |
= flag
;
347 map
->map
[list
->min
++] = list
->map
++;
350 if
(list
->min
> list
->max
) {
355 run
= list
->max
- list
->min
+ 1;
357 if
(!(r
= map
->root
) ||
(list
->max
< r
->min
- 1)
358 ||
(!flag
&& list
->max
== r
->min
- 1)) {
360 list
->types
= xlalloc
(run
);
361 for
(i
= 0; i
< run
; ++i
)
362 list
->types
[i
] = flag
;
364 list
->next
= map
->root
;
369 for
(r
= map
->root
; r
&& r
->max
+ 1 < list
->min
; r
= r
->next
)
374 * We are off the end.
377 list
->types
= xlalloc
(run
);
378 for
(i
= 0; i
< run
; ++i
)
379 list
->types
[i
] = flag
;
386 if
(list
->max
< r
->min
- 1) {
388 * We come before this range and we do not intersect it.
389 * We are not before the root node, it was checked before the loop
392 list
->types
= xlalloc
(run
);
393 for
(i
= 0; i
< run
; ++i
)
394 list
->types
[i
] = flag
;
396 list
->next
= lr
->next
;
402 * At this point we have found that we at least intersect with
403 * the range pointed to by `r', we might intersect with one or
404 * more ranges beyond `r' as well.
407 if
(!flag
&& list
->map
- list
->min
!= r
->map
- r
->min
) {
409 * There are only two cases when we are doing case maps and
410 * our maps needn't have the same offset. When we are adjoining
411 * but not intersecting.
413 if
(list
->max
+ 1 == r
->min
) {
418 if
(list
->min
- 1 == r
->max
) {
419 list
->next
= r
->next
;
423 errx
(1, "error: conflicting map entries");
426 if
(list
->min
>= r
->min
&& list
->max
<= r
->max
) {
432 for
(i
= list
->min
; i
<= list
->max
; ++i
)
433 r
->types
[i
- r
->min
] |
= flag
;
438 if
(list
->min
<= r
->min
&& list
->max
>= r
->max
) {
440 * Superset case. Make him big enough to hold us.
441 * We might need to merge with the guy after him.
444 list
->types
= xlalloc
(list
->max
- list
->min
+ 1);
446 for
(i
= list
->min
; i
<= list
->max
; ++i
)
447 list
->types
[i
- list
->min
] = flag
;
449 for
(i
= r
->min
; i
<= r
->max
; ++i
)
450 list
->types
[i
- list
->min
] |
= r
->types
[i
- r
->min
];
453 r
->types
= list
->types
;
460 } else if
(list
->min
< r
->min
) {
462 * Our tail intersects his head.
465 list
->types
= xlalloc
(r
->max
- list
->min
+ 1);
467 for
(i
= r
->min
; i
<= r
->max
; ++i
)
468 list
->types
[i
- list
->min
] = r
->types
[i
- r
->min
];
470 for
(i
= list
->min
; i
< r
->min
; ++i
)
471 list
->types
[i
- list
->min
] = flag
;
473 for
(i
= r
->min
; i
<= list
->max
; ++i
)
474 list
->types
[i
- list
->min
] |
= flag
;
477 r
->types
= list
->types
;
486 * Our head intersects his tail.
487 * We might need to merge with the guy after him.
490 r
->types
= xrelalloc
(r
->types
, list
->max
- r
->min
+ 1);
492 for
(i
= list
->min
; i
<= r
->max
; ++i
)
493 r
->types
[i
- r
->min
] |
= flag
;
495 for
(i
= r
->max
+1; i
<= list
->max
; ++i
)
496 r
->types
[i
- r
->min
] = flag
;
503 * Okay, check to see if we grew into the next guy(s)
505 while
((lr
= r
->next
) && r
->max
>= lr
->min
) {
507 if
(r
->max
>= lr
->max
) {
509 * Good, we consumed all of him.
511 for
(i
= lr
->min
; i
<= lr
->max
; ++i
)
512 r
->types
[i
- r
->min
] |
= lr
->types
[i
- lr
->min
];
515 * "append" him on to the end of us.
517 r
->types
= xrelalloc
(r
->types
, lr
->max
- r
->min
+ 1);
519 for
(i
= lr
->min
; i
<= r
->max
; ++i
)
520 r
->types
[i
- r
->min
] |
= lr
->types
[i
- lr
->min
];
522 for
(i
= r
->max
+1; i
<= lr
->max
; ++i
)
523 r
->types
[i
- r
->min
] = lr
->types
[i
- lr
->min
];
528 if
(lr
->max
> r
->max
)
543 int x
, first_d
, curr_d
;
547 * See if we can compress some of the istype arrays
549 for
(list
= types.root
; list
; list
= list
->next
) {
550 list
->map
= list
->types
[0];
551 for
(x
= 1; x
< list
->max
- list
->min
+ 1; ++x
) {
552 if
((int32_t)list
->types
[x
] != list
->map
) {
559 first_d
= curr_d
= -1;
560 for
(x
= 0; x
< _CACHED_RUNES
; ++x
) {
561 uint32_t r
= types.map
[x
];
565 first_d
= curr_d
= x
;
566 else if
(x
!= curr_d
+ 1)
567 errx
(1, "error: DIGIT range is not contiguous");
568 else if
(x
- first_d
> 9)
569 errx
(1, "error: DIGIT range is too big");
574 "error: DIGIT range is not a subset of XDIGIT range");
578 errx
(1, "error: no DIGIT range defined in the single byte area");
579 else if
(curr_d
- first_d
< 9)
580 errx
(1, "error: DIGIT range is too small in the single byte area");
583 * Fill in our tables. Do this in network order so that
584 * diverse machines have a chance of sharing data.
585 * (Machines like Crays cannot share with little machines due to
586 * word size. Sigh. We tried.)
588 for
(x
= 0; x
< _CACHED_RUNES
; ++x
) {
589 new_locale.runetype
[x
] = htonl
(types.map
[x
]);
590 new_locale.maplower
[x
] = htonl
(maplower.map
[x
]);
591 new_locale.mapupper
[x
] = htonl
(mapupper.map
[x
]);
595 * Count up how many ranges we will need for each of the extents.
600 new_locale.runetype_ext_nranges
++;
603 new_locale.runetype_ext_nranges
=
604 htonl
(new_locale.runetype_ext_nranges
);
606 list
= maplower.root
;
609 new_locale.maplower_ext_nranges
++;
612 new_locale.maplower_ext_nranges
=
613 htonl
(new_locale.maplower_ext_nranges
);
615 list
= mapupper.root
;
618 new_locale.mapupper_ext_nranges
++;
621 new_locale.mapupper_ext_nranges
=
622 htonl
(new_locale.mapupper_ext_nranges
);
624 new_locale.variable_len
= htonl
(new_locale.variable_len
);
627 * Okay, we are now ready to write the new locale file.
631 * PART 1: The _FileRuneLocale structure
633 if
(fwrite
((char *)&new_locale
, sizeof
(new_locale
), 1, fp
) != 1) {
638 * PART 2: The runetype_ext structures (not the actual tables)
645 re.min
= htonl
(list
->min
);
646 re.max
= htonl
(list
->max
);
647 re.map
= htonl
(list
->map
);
649 if
(fwrite
((char *)&re
, sizeof
(re
), 1, fp
) != 1) {
657 * PART 3: The maplower_ext structures
659 list
= maplower.root
;
664 re.min
= htonl
(list
->min
);
665 re.max
= htonl
(list
->max
);
666 re.map
= htonl
(list
->map
);
668 if
(fwrite
((char *)&re
, sizeof
(re
), 1, fp
) != 1) {
676 * PART 4: The mapupper_ext structures
678 list
= mapupper.root
;
683 re.min
= htonl
(list
->min
);
684 re.max
= htonl
(list
->max
);
685 re.map
= htonl
(list
->map
);
687 if
(fwrite
((char *)&re
, sizeof
(re
), 1, fp
) != 1) {
695 * PART 5: The runetype_ext tables
700 for
(x
= 0; x
< list
->max
- list
->min
+ 1; ++x
)
701 list
->types
[x
] = htonl
(list
->types
[x
]);
704 if
(fwrite
((char *)list
->types
,
705 (list
->max
- list
->min
+ 1) * sizeof
(uint32_t),
714 * PART 6: And finally the variable data
716 if
(new_locale.variable_len
!= 0 &&
717 fwrite
(variable
, ntohl
(new_locale.variable_len
), 1, fp
) != 1) {
721 if
(fclose
(fp
) != 0) {
730 if
(new_locale.encoding
[0])
731 fprintf
(stderr
, "ENCODING %s\n", new_locale.encoding
);
733 fprintf
(stderr
, "VARIABLE %s\n", variable
);
735 fprintf
(stderr
, "\nMAPLOWER:\n\n");
737 for
(x
= 0; x
< _CACHED_RUNES
; ++x
) {
738 if
(isprint
(maplower.map
[x
]))
739 fprintf
(stderr
, " '%c'", (int)maplower.map
[x
]);
740 else if
(maplower.map
[x
])
741 fprintf
(stderr
, "%04x", maplower.map
[x
]);
743 fprintf
(stderr
, "%4x", 0);
744 if
((x
& 0xf) == 0xf)
745 fprintf
(stderr
, "\n");
747 fprintf
(stderr
, " ");
749 fprintf
(stderr
, "\n");
751 for
(list
= maplower.root
; list
; list
= list
->next
)
752 fprintf
(stderr
, "\t%04x - %04x : %04x\n", list
->min
, list
->max
, list
->map
);
754 fprintf
(stderr
, "\nMAPUPPER:\n\n");
756 for
(x
= 0; x
< _CACHED_RUNES
; ++x
) {
757 if
(isprint
(mapupper.map
[x
]))
758 fprintf
(stderr
, " '%c'", (int)mapupper.map
[x
]);
759 else if
(mapupper.map
[x
])
760 fprintf
(stderr
, "%04x", mapupper.map
[x
]);
762 fprintf
(stderr
, "%4x", 0);
763 if
((x
& 0xf) == 0xf)
764 fprintf
(stderr
, "\n");
766 fprintf
(stderr
, " ");
768 fprintf
(stderr
, "\n");
770 for
(list
= mapupper.root
; list
; list
= list
->next
)
771 fprintf
(stderr
, "\t%04x - %04x : %04x\n", list
->min
, list
->max
, list
->map
);
774 fprintf
(stderr
, "\nTYPES:\n\n");
776 for
(x
= 0; x
< _CACHED_RUNES
; ++x
) {
777 uint32_t r
= types.map
[x
];
781 fprintf
(stderr
, " '%c': %2d", x
, (int)(r
& 0xff));
783 fprintf
(stderr
, "%04x: %2d", x
, (int)(r
& 0xff));
785 fprintf
(stderr
, " %4s", (r
& _CTYPE_A
) ?
"alph" : "");
786 fprintf
(stderr
, " %4s", (r
& _CTYPE_C
) ?
"ctrl" : "");
787 fprintf
(stderr
, " %4s", (r
& _CTYPE_D
) ?
"dig" : "");
788 fprintf
(stderr
, " %4s", (r
& _CTYPE_G
) ?
"graf" : "");
789 fprintf
(stderr
, " %4s", (r
& _CTYPE_L
) ?
"low" : "");
790 fprintf
(stderr
, " %4s", (r
& _CTYPE_P
) ?
"punc" : "");
791 fprintf
(stderr
, " %4s", (r
& _CTYPE_S
) ?
"spac" : "");
792 fprintf
(stderr
, " %4s", (r
& _CTYPE_U
) ?
"upp" : "");
793 fprintf
(stderr
, " %4s", (r
& _CTYPE_X
) ?
"xdig" : "");
794 fprintf
(stderr
, " %4s", (r
& _CTYPE_B
) ?
"blnk" : "");
795 fprintf
(stderr
, " %4s", (r
& _CTYPE_R
) ?
"prnt" : "");
796 fprintf
(stderr
, " %4s", (r
& _CTYPE_I
) ?
"ideo" : "");
797 fprintf
(stderr
, " %4s", (r
& _CTYPE_T
) ?
"spec" : "");
798 fprintf
(stderr
, " %4s", (r
& _CTYPE_Q
) ?
"phon" : "");
799 fprintf
(stderr
, "\n");
803 for
(list
= types.root
; list
; list
= list
->next
) {
804 if
(list
->map
&& list
->min
+ 3 < list
->max
) {
805 uint32_t r
= list
->map
;
807 fprintf
(stderr
, "%04x: %2d",
808 (uint32_t)list
->min
, (int)(r
& 0xff));
810 fprintf
(stderr
, " %4s", (r
& _CTYPE_A
) ?
"alph" : "");
811 fprintf
(stderr
, " %4s", (r
& _CTYPE_C
) ?
"ctrl" : "");
812 fprintf
(stderr
, " %4s", (r
& _CTYPE_D
) ?
"dig" : "");
813 fprintf
(stderr
, " %4s", (r
& _CTYPE_G
) ?
"graf" : "");
814 fprintf
(stderr
, " %4s", (r
& _CTYPE_L
) ?
"low" : "");
815 fprintf
(stderr
, " %4s", (r
& _CTYPE_P
) ?
"punc" : "");
816 fprintf
(stderr
, " %4s", (r
& _CTYPE_S
) ?
"spac" : "");
817 fprintf
(stderr
, " %4s", (r
& _CTYPE_U
) ?
"upp" : "");
818 fprintf
(stderr
, " %4s", (r
& _CTYPE_X
) ?
"xdig" : "");
819 fprintf
(stderr
, " %4s", (r
& _CTYPE_B
) ?
"blnk" : "");
820 fprintf
(stderr
, " %4s", (r
& _CTYPE_R
) ?
"prnt" : "");
821 fprintf
(stderr
, " %4s", (r
& _CTYPE_I
) ?
"ideo" : "");
822 fprintf
(stderr
, " %4s", (r
& _CTYPE_T
) ?
"spec" : "");
823 fprintf
(stderr
, " %4s", (r
& _CTYPE_Q
) ?
"phon" : "");
824 fprintf
(stderr
, "\n...\n");
826 fprintf
(stderr
, "%04x: %2d",
827 (uint32_t)list
->max
, (int)(r
& 0xff));
829 fprintf
(stderr
, " %4s", (r
& _CTYPE_A
) ?
"alph" : "");
830 fprintf
(stderr
, " %4s", (r
& _CTYPE_C
) ?
"ctrl" : "");
831 fprintf
(stderr
, " %4s", (r
& _CTYPE_D
) ?
"dig" : "");
832 fprintf
(stderr
, " %4s", (r
& _CTYPE_G
) ?
"graf" : "");
833 fprintf
(stderr
, " %4s", (r
& _CTYPE_L
) ?
"low" : "");
834 fprintf
(stderr
, " %4s", (r
& _CTYPE_P
) ?
"punc" : "");
835 fprintf
(stderr
, " %4s", (r
& _CTYPE_S
) ?
"spac" : "");
836 fprintf
(stderr
, " %4s", (r
& _CTYPE_U
) ?
"upp" : "");
837 fprintf
(stderr
, " %4s", (r
& _CTYPE_X
) ?
"xdig" : "");
838 fprintf
(stderr
, " %4s", (r
& _CTYPE_B
) ?
"blnk" : "");
839 fprintf
(stderr
, " %4s", (r
& _CTYPE_R
) ?
"prnt" : "");
840 fprintf
(stderr
, " %4s", (r
& _CTYPE_I
) ?
"ideo" : "");
841 fprintf
(stderr
, " %4s", (r
& _CTYPE_T
) ?
"spec" : "");
842 fprintf
(stderr
, " %4s", (r
& _CTYPE_Q
) ?
"phon" : "");
843 fprintf
(stderr
, "\n");
845 for
(x
= list
->min
; x
<= list
->max
; ++x
) {
846 uint32_t r
= ntohl
(list
->types
[x
- list
->min
]);
849 fprintf
(stderr
, "%04x: %2d", x
, (int)(r
& 0xff));
851 fprintf
(stderr
, " %4s", (r
& _CTYPE_A
) ?
"alph" : "");
852 fprintf
(stderr
, " %4s", (r
& _CTYPE_C
) ?
"ctrl" : "");
853 fprintf
(stderr
, " %4s", (r
& _CTYPE_D
) ?
"dig" : "");
854 fprintf
(stderr
, " %4s", (r
& _CTYPE_G
) ?
"graf" : "");
855 fprintf
(stderr
, " %4s", (r
& _CTYPE_L
) ?
"low" : "");
856 fprintf
(stderr
, " %4s", (r
& _CTYPE_P
) ?
"punc" : "");
857 fprintf
(stderr
, " %4s", (r
& _CTYPE_S
) ?
"spac" : "");
858 fprintf
(stderr
, " %4s", (r
& _CTYPE_U
) ?
"upp" : "");
859 fprintf
(stderr
, " %4s", (r
& _CTYPE_X
) ?
"xdig" : "");
860 fprintf
(stderr
, " %4s", (r
& _CTYPE_B
) ?
"blnk" : "");
861 fprintf
(stderr
, " %4s", (r
& _CTYPE_R
) ?
"prnt" : "");
862 fprintf
(stderr
, " %4s", (r
& _CTYPE_I
) ?
"ideo" : "");
863 fprintf
(stderr
, " %4s", (r
& _CTYPE_T
) ?
"spec" : "");
864 fprintf
(stderr
, " %4s", (r
& _CTYPE_Q
) ?
"phon" : "");
865 fprintf
(stderr
, "\n");