3 * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
4 * at Electronni Visti IA, Kiev, Ukraine.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 void yyerror(char *fmt, ...) __printflike(1, 2);
45 static void usage __P((void));
47 char map_name[FILENAME_MAX] = ".";
49 char __collate_version[STR_LEN];
50 u_char charmap_table[UCHAR_MAX + 1][STR_LEN];
51 u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
52 struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
53 struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE];
55 int prim_pri = 1, sec_pri = 1;
60 char *out_file = "LC_COLLATE";
66 %token SUBSTITUTE WITH ORDER RANGE
72 collate : statment_list
74 statment_list : statment
75 | statment_list '\n' statment
83 strcpy(charmap_table[$2], $1);
86 substitute : SUBSTITUTE CHAR WITH STRING {
88 yyerror("NUL character can't be substituted");
89 if (strchr($4, $2) != NULL)
90 yyerror("Char 0x%02x substitution is recursive", $2);
91 strcpy(__collate_substitute_table[$2], $4);
94 order : ORDER order_list {
96 int ch, substed, ordered;
98 for (ch = 0; ch < UCHAR_MAX + 1; ch++) {
99 substed = (__collate_substitute_table[ch][0] != ch);
100 ordered = !!__collate_char_pri_table[ch].prim;
101 if (!ordered && !substed)
102 yyerror("Char 0x%02x not found", ch);
103 if (substed && ordered)
104 yyerror("Char 0x%02x can't be ordered since substituted", ch);
107 fp = fopen(out_file, "w");
109 err(EX_UNAVAILABLE, "can't open destination file %s",
112 strcpy(__collate_version, COLLATE_VERSION);
113 fwrite(__collate_version, sizeof(__collate_version), 1, fp);
114 fwrite(__collate_substitute_table, sizeof(__collate_substitute_table), 1, fp);
115 fwrite(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, fp);
116 fwrite(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp);
118 err(EX_UNAVAILABLE, "IO error writting to destination file %s",
123 collate_print_tables();
129 | order_list ';' item
132 if (__collate_char_pri_table[$1].prim)
133 yyerror("Char 0x%02x duplicated", $1);
134 __collate_char_pri_table[$1].prim = prim_pri++;
137 if (chain_index >= TABLE_SIZE - 1)
138 yyerror("__collate_chain_pri_table overflow");
139 strcpy(__collate_chain_pri_table[chain_index].str, $1);
140 __collate_chain_pri_table[chain_index++].prim = prim_pri++;
146 yyerror("Illegal range 0x%02x -- 0x%02x", $1, $3);
148 for (i = $1; i <= $3; i++) {
149 if (__collate_char_pri_table[(u_char)i].prim)
150 yyerror("Char 0x%02x duplicated", (u_char)i);
151 __collate_char_pri_table[(u_char)i].prim = prim_pri++;
154 | '{' prim_order_list '}' {
157 | '(' sec_order_list ')' {
162 prim_order_list : prim_sub_item
163 | prim_order_list ',' prim_sub_item
165 sec_order_list : sec_sub_item
166 | sec_order_list ',' sec_sub_item
168 prim_sub_item : CHAR {
169 if (__collate_char_pri_table[$1].prim)
170 yyerror("Char 0x%02x duplicated", $1);
171 __collate_char_pri_table[$1].prim = prim_pri;
177 yyerror("Illegal range 0x%02x -- 0x%02x",
180 for (i = $1; i <= $3; i++) {
181 if (__collate_char_pri_table[(u_char)i].prim)
182 yyerror("Char 0x%02x duplicated", (u_char)i);
183 __collate_char_pri_table[(u_char)i].prim = prim_pri;
187 if (chain_index >= TABLE_SIZE - 1)
188 yyerror("__collate_chain_pri_table overflow");
189 strcpy(__collate_chain_pri_table[chain_index].str, $1);
190 __collate_chain_pri_table[chain_index++].prim = prim_pri;
193 sec_sub_item : CHAR {
194 if (__collate_char_pri_table[$1].prim)
195 yyerror("Char 0x%02x duplicated", $1);
196 __collate_char_pri_table[$1].prim = prim_pri;
197 __collate_char_pri_table[$1].sec = sec_pri++;
203 yyerror("Illegal range 0x%02x -- 0x%02x",
206 for (i = $1; i <= $3; i++) {
207 if (__collate_char_pri_table[(u_char)i].prim)
208 yyerror("Char 0x%02x duplicated", (u_char)i);
209 __collate_char_pri_table[(u_char)i].prim = prim_pri;
210 __collate_char_pri_table[(u_char)i].sec = sec_pri++;
214 if (chain_index >= TABLE_SIZE - 1)
215 yyerror("__collate_chain_pri_table overflow");
216 strcpy(__collate_chain_pri_table[chain_index].str, $1);
217 __collate_chain_pri_table[chain_index].prim = prim_pri;
218 __collate_chain_pri_table[chain_index++].sec = sec_pri++;
229 while((ch = getopt(ac, av, ":do:I:")) != EOF) {
231 while((ch = getopt(ac, av, ":o:I:")) != EOF) {
245 strcpy(map_name, optarg);
255 if((yyin = fopen(*av, "r")) == 0)
256 err(EX_UNAVAILABLE, "can't open source file %s", *av);
258 for(ch = 0; ch <= UCHAR_MAX; ch++)
259 __collate_substitute_table[ch][0] = ch;
267 fprintf(stderr, "usage: colldef [-o out_file] [-I map_dir] [filename]\n");
271 void yyerror(char *fmt, ...)
277 vsnprintf(msg, sizeof(msg), fmt, ap);
279 errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no);
284 collate_print_tables()
287 struct __collate_st_chain_pri *p2;
289 printf("Substitute table:\n");
290 for (i = 0; i < UCHAR_MAX + 1; i++)
291 if (i != *__collate_substitute_table[i])
292 printf("\t'%c' --> \"%s\"\n", i,
293 __collate_substitute_table[i]);
294 printf("Chain priority table:\n");
295 for (p2 = __collate_chain_pri_table; p2->str[0]; p2++)
296 printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec);
297 printf("Char priority table:\n");
298 for (i = 0; i < UCHAR_MAX + 1; i++)
299 printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim,
300 __collate_char_pri_table[i].sec);