1%{ 2/*- 3 * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 4 * at Electronni Visti IA, Kiev, Ukraine. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 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. 15 * 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 26 * SUCH DAMAGE.
| 1%{ 2/*- 3 * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 4 * at Electronni Visti IA, Kiev, Ukraine. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 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. 15 * 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 26 * SUCH DAMAGE.
|
27 * 28 * $FreeBSD: head/usr.bin/colldef/parse.y 87052 2001-11-28 09:50:24Z ache $
| |
29 */ 30
| 27 */ 28
|
| 29#include <sys/cdefs.h> 30 31__FBSDID("$FreeBSD: head/usr.bin/colldef/parse.y 87243 2001-12-02 23:40:46Z markm $"); 32
|
31#include <err.h> 32#include <stdarg.h> 33#include <stdio.h> 34#include <string.h> 35#include <stdlib.h> 36#include <unistd.h> 37#include <sysexits.h> 38#include "collate.h" 39#include "common.h" 40 41extern FILE *yyin;
| 33#include <err.h> 34#include <stdarg.h> 35#include <stdio.h> 36#include <string.h> 37#include <stdlib.h> 38#include <unistd.h> 39#include <sysexits.h> 40#include "collate.h" 41#include "common.h" 42 43extern FILE *yyin;
|
42void yyerror(char *fmt, ...) __printflike(1, 2);
| 44void yyerror(const char *fmt, ...) __printflike(1, 2);
|
43int yyparse(void); 44int yylex(void);
| 45int yyparse(void); 46int yylex(void);
|
45static void usage __P((void));
| 47static void usage(void); 48static void collate_print_tables(void);
|
46 47char map_name[FILENAME_MAX] = "."; 48 49char __collate_version[STR_LEN]; 50u_char charmap_table[UCHAR_MAX + 1][CHARMAP_SYMBOL_LEN]; 51u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; 52struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; 53struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE]; 54int chain_index; 55int prim_pri = 1, sec_pri = 1; 56#ifdef COLLATE_DEBUG 57int debug; 58#endif 59
| 49 50char map_name[FILENAME_MAX] = "."; 51 52char __collate_version[STR_LEN]; 53u_char charmap_table[UCHAR_MAX + 1][CHARMAP_SYMBOL_LEN]; 54u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; 55struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; 56struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE]; 57int chain_index; 58int prim_pri = 1, sec_pri = 1; 59#ifdef COLLATE_DEBUG 60int debug; 61#endif 62
|
60char *out_file = "LC_COLLATE";
| 63const char *out_file = "LC_COLLATE";
|
61%} 62%union { 63 u_char ch; 64 u_char str[BUFSIZE]; 65} 66%token SUBSTITUTE WITH ORDER RANGE 67%token <str> STRING 68%token <str> CHAIN 69%token <str> DEFN 70%token <ch> CHAR 71%% 72collate : statment_list 73; 74statment_list : statment 75 | statment_list '\n' statment 76; 77statment : 78 | charmap 79 | substitute 80 | order 81; 82charmap : DEFN CHAR { 83 if (strlen($1) + 1 > CHARMAP_SYMBOL_LEN) 84 yyerror("Charmap symbol name '%s' is too long", $1); 85 strcpy(charmap_table[$2], $1); 86} 87; 88substitute : SUBSTITUTE CHAR WITH STRING { 89 if ($2 == '\0') 90 yyerror("NUL character can't be substituted"); 91 if (strchr($4, $2) != NULL) 92 yyerror("Char 0x%02x substitution is recursive", $2); 93 if (strlen($4) + 1 > STR_LEN) 94 yyerror("Char 0x%02x substitution is too long", $2); 95 strcpy(__collate_substitute_table[$2], $4); 96} 97; 98order : ORDER order_list { 99 FILE *fp; 100 int ch, substed, ordered; 101 102 for (ch = 0; ch < UCHAR_MAX + 1; ch++) { 103 substed = (__collate_substitute_table[ch][0] != ch); 104 ordered = !!__collate_char_pri_table[ch].prim; 105 if (!ordered && !substed) 106 yyerror("Char 0x%02x not found", ch); 107 if (substed && ordered) 108 yyerror("Char 0x%02x can't be ordered since substituted", ch); 109 } 110 111 fp = fopen(out_file, "w"); 112 if(!fp) 113 err(EX_UNAVAILABLE, "can't open destination file %s", 114 out_file); 115 116 strcpy(__collate_version, COLLATE_VERSION); 117 fwrite(__collate_version, sizeof(__collate_version), 1, fp); 118 fwrite(__collate_substitute_table, sizeof(__collate_substitute_table), 1, fp); 119 fwrite(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); 120 fwrite(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp); 121 if (fflush(fp)) 122 err(EX_UNAVAILABLE, "IO error writting to destination file %s", 123 out_file); 124 fclose(fp); 125#ifdef COLLATE_DEBUG 126 if (debug) 127 collate_print_tables(); 128#endif 129 exit(EX_OK); 130} 131; 132order_list : item 133 | order_list ';' item 134; 135item : CHAR { 136 if (__collate_char_pri_table[$1].prim) 137 yyerror("Char 0x%02x duplicated", $1); 138 __collate_char_pri_table[$1].prim = prim_pri++; 139} 140 | CHAIN { 141 if (chain_index >= TABLE_SIZE - 1) 142 yyerror("__collate_chain_pri_table overflow"); 143 if (strlen($1) + 1 > STR_LEN) 144 yyerror("Chain %d is too long", chain_index); 145 strcpy(__collate_chain_pri_table[chain_index].str, $1); 146 __collate_chain_pri_table[chain_index++].prim = prim_pri++; 147} 148 | CHAR RANGE CHAR { 149 u_int i; 150 151 if ($3 <= $1) 152 yyerror("Illegal range 0x%02x -- 0x%02x", $1, $3); 153 154 for (i = $1; i <= $3; i++) { 155 if (__collate_char_pri_table[(u_char)i].prim) 156 yyerror("Char 0x%02x duplicated", (u_char)i); 157 __collate_char_pri_table[(u_char)i].prim = prim_pri++; 158 } 159} 160 | '{' prim_order_list '}' { 161 prim_pri++; 162} 163 | '(' sec_order_list ')' { 164 prim_pri++; 165 sec_pri = 1; 166} 167; 168prim_order_list : prim_sub_item 169 | prim_order_list ',' prim_sub_item 170; 171sec_order_list : sec_sub_item 172 | sec_order_list ',' sec_sub_item 173; 174prim_sub_item : CHAR { 175 if (__collate_char_pri_table[$1].prim) 176 yyerror("Char 0x%02x duplicated", $1); 177 __collate_char_pri_table[$1].prim = prim_pri; 178} 179 | CHAR RANGE CHAR { 180 u_int i; 181 182 if ($3 <= $1) 183 yyerror("Illegal range 0x%02x -- 0x%02x", 184 $1, $3); 185 186 for (i = $1; i <= $3; i++) { 187 if (__collate_char_pri_table[(u_char)i].prim) 188 yyerror("Char 0x%02x duplicated", (u_char)i); 189 __collate_char_pri_table[(u_char)i].prim = prim_pri; 190 } 191} 192 | CHAIN { 193 if (chain_index >= TABLE_SIZE - 1) 194 yyerror("__collate_chain_pri_table overflow"); 195 if (strlen($1) + 1 > STR_LEN) 196 yyerror("Chain %d is too long", chain_index); 197 strcpy(__collate_chain_pri_table[chain_index].str, $1); 198 __collate_chain_pri_table[chain_index++].prim = prim_pri; 199} 200; 201sec_sub_item : CHAR { 202 if (__collate_char_pri_table[$1].prim) 203 yyerror("Char 0x%02x duplicated", $1); 204 __collate_char_pri_table[$1].prim = prim_pri; 205 __collate_char_pri_table[$1].sec = sec_pri++; 206} 207 | CHAR RANGE CHAR { 208 u_int i; 209 210 if ($3 <= $1) 211 yyerror("Illegal range 0x%02x -- 0x%02x", 212 $1, $3); 213 214 for (i = $1; i <= $3; i++) { 215 if (__collate_char_pri_table[(u_char)i].prim) 216 yyerror("Char 0x%02x duplicated", (u_char)i); 217 __collate_char_pri_table[(u_char)i].prim = prim_pri; 218 __collate_char_pri_table[(u_char)i].sec = sec_pri++; 219 } 220} 221 | CHAIN { 222 if (chain_index >= TABLE_SIZE - 1) 223 yyerror("__collate_chain_pri_table overflow"); 224 if (strlen($1) + 1 > STR_LEN) 225 yyerror("Chain %d is too long", chain_index); 226 strcpy(__collate_chain_pri_table[chain_index].str, $1); 227 __collate_chain_pri_table[chain_index].prim = prim_pri; 228 __collate_chain_pri_table[chain_index++].sec = sec_pri++; 229} 230; 231%% 232int 233main(ac, av)
| 64%} 65%union { 66 u_char ch; 67 u_char str[BUFSIZE]; 68} 69%token SUBSTITUTE WITH ORDER RANGE 70%token <str> STRING 71%token <str> CHAIN 72%token <str> DEFN 73%token <ch> CHAR 74%% 75collate : statment_list 76; 77statment_list : statment 78 | statment_list '\n' statment 79; 80statment : 81 | charmap 82 | substitute 83 | order 84; 85charmap : DEFN CHAR { 86 if (strlen($1) + 1 > CHARMAP_SYMBOL_LEN) 87 yyerror("Charmap symbol name '%s' is too long", $1); 88 strcpy(charmap_table[$2], $1); 89} 90; 91substitute : SUBSTITUTE CHAR WITH STRING { 92 if ($2 == '\0') 93 yyerror("NUL character can't be substituted"); 94 if (strchr($4, $2) != NULL) 95 yyerror("Char 0x%02x substitution is recursive", $2); 96 if (strlen($4) + 1 > STR_LEN) 97 yyerror("Char 0x%02x substitution is too long", $2); 98 strcpy(__collate_substitute_table[$2], $4); 99} 100; 101order : ORDER order_list { 102 FILE *fp; 103 int ch, substed, ordered; 104 105 for (ch = 0; ch < UCHAR_MAX + 1; ch++) { 106 substed = (__collate_substitute_table[ch][0] != ch); 107 ordered = !!__collate_char_pri_table[ch].prim; 108 if (!ordered && !substed) 109 yyerror("Char 0x%02x not found", ch); 110 if (substed && ordered) 111 yyerror("Char 0x%02x can't be ordered since substituted", ch); 112 } 113 114 fp = fopen(out_file, "w"); 115 if(!fp) 116 err(EX_UNAVAILABLE, "can't open destination file %s", 117 out_file); 118 119 strcpy(__collate_version, COLLATE_VERSION); 120 fwrite(__collate_version, sizeof(__collate_version), 1, fp); 121 fwrite(__collate_substitute_table, sizeof(__collate_substitute_table), 1, fp); 122 fwrite(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); 123 fwrite(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp); 124 if (fflush(fp)) 125 err(EX_UNAVAILABLE, "IO error writting to destination file %s", 126 out_file); 127 fclose(fp); 128#ifdef COLLATE_DEBUG 129 if (debug) 130 collate_print_tables(); 131#endif 132 exit(EX_OK); 133} 134; 135order_list : item 136 | order_list ';' item 137; 138item : CHAR { 139 if (__collate_char_pri_table[$1].prim) 140 yyerror("Char 0x%02x duplicated", $1); 141 __collate_char_pri_table[$1].prim = prim_pri++; 142} 143 | CHAIN { 144 if (chain_index >= TABLE_SIZE - 1) 145 yyerror("__collate_chain_pri_table overflow"); 146 if (strlen($1) + 1 > STR_LEN) 147 yyerror("Chain %d is too long", chain_index); 148 strcpy(__collate_chain_pri_table[chain_index].str, $1); 149 __collate_chain_pri_table[chain_index++].prim = prim_pri++; 150} 151 | CHAR RANGE CHAR { 152 u_int i; 153 154 if ($3 <= $1) 155 yyerror("Illegal range 0x%02x -- 0x%02x", $1, $3); 156 157 for (i = $1; i <= $3; i++) { 158 if (__collate_char_pri_table[(u_char)i].prim) 159 yyerror("Char 0x%02x duplicated", (u_char)i); 160 __collate_char_pri_table[(u_char)i].prim = prim_pri++; 161 } 162} 163 | '{' prim_order_list '}' { 164 prim_pri++; 165} 166 | '(' sec_order_list ')' { 167 prim_pri++; 168 sec_pri = 1; 169} 170; 171prim_order_list : prim_sub_item 172 | prim_order_list ',' prim_sub_item 173; 174sec_order_list : sec_sub_item 175 | sec_order_list ',' sec_sub_item 176; 177prim_sub_item : CHAR { 178 if (__collate_char_pri_table[$1].prim) 179 yyerror("Char 0x%02x duplicated", $1); 180 __collate_char_pri_table[$1].prim = prim_pri; 181} 182 | CHAR RANGE CHAR { 183 u_int i; 184 185 if ($3 <= $1) 186 yyerror("Illegal range 0x%02x -- 0x%02x", 187 $1, $3); 188 189 for (i = $1; i <= $3; i++) { 190 if (__collate_char_pri_table[(u_char)i].prim) 191 yyerror("Char 0x%02x duplicated", (u_char)i); 192 __collate_char_pri_table[(u_char)i].prim = prim_pri; 193 } 194} 195 | CHAIN { 196 if (chain_index >= TABLE_SIZE - 1) 197 yyerror("__collate_chain_pri_table overflow"); 198 if (strlen($1) + 1 > STR_LEN) 199 yyerror("Chain %d is too long", chain_index); 200 strcpy(__collate_chain_pri_table[chain_index].str, $1); 201 __collate_chain_pri_table[chain_index++].prim = prim_pri; 202} 203; 204sec_sub_item : CHAR { 205 if (__collate_char_pri_table[$1].prim) 206 yyerror("Char 0x%02x duplicated", $1); 207 __collate_char_pri_table[$1].prim = prim_pri; 208 __collate_char_pri_table[$1].sec = sec_pri++; 209} 210 | CHAR RANGE CHAR { 211 u_int i; 212 213 if ($3 <= $1) 214 yyerror("Illegal range 0x%02x -- 0x%02x", 215 $1, $3); 216 217 for (i = $1; i <= $3; i++) { 218 if (__collate_char_pri_table[(u_char)i].prim) 219 yyerror("Char 0x%02x duplicated", (u_char)i); 220 __collate_char_pri_table[(u_char)i].prim = prim_pri; 221 __collate_char_pri_table[(u_char)i].sec = sec_pri++; 222 } 223} 224 | CHAIN { 225 if (chain_index >= TABLE_SIZE - 1) 226 yyerror("__collate_chain_pri_table overflow"); 227 if (strlen($1) + 1 > STR_LEN) 228 yyerror("Chain %d is too long", chain_index); 229 strcpy(__collate_chain_pri_table[chain_index].str, $1); 230 __collate_chain_pri_table[chain_index].prim = prim_pri; 231 __collate_chain_pri_table[chain_index++].sec = sec_pri++; 232} 233; 234%% 235int 236main(ac, av)
|
| 237 int ac;
|
234 char **av; 235{ 236 int ch; 237 238#ifdef COLLATE_DEBUG 239 while((ch = getopt(ac, av, ":do:I:")) != EOF) { 240#else 241 while((ch = getopt(ac, av, ":o:I:")) != EOF) { 242#endif 243 switch (ch) 244 { 245#ifdef COLLATE_DEBUG 246 case 'd': 247 debug++; 248 break; 249#endif 250 case 'o': 251 out_file = optarg; 252 break; 253 254 case 'I': 255 strlcpy(map_name, optarg, sizeof(map_name)); 256 break; 257 258 default: 259 usage(); 260 } 261 } 262 ac -= optind; 263 av += optind; 264 if(ac > 0) { 265 if((yyin = fopen(*av, "r")) == 0) 266 err(EX_UNAVAILABLE, "can't open source file %s", *av); 267 } 268 for(ch = 0; ch <= UCHAR_MAX; ch++) 269 __collate_substitute_table[ch][0] = ch; 270 yyparse(); 271 return 0; 272} 273 274static void 275usage() 276{ 277 fprintf(stderr, "usage: colldef [-o out_file] [-I map_dir] [filename]\n"); 278 exit(EX_USAGE); 279} 280
| 238 char **av; 239{ 240 int ch; 241 242#ifdef COLLATE_DEBUG 243 while((ch = getopt(ac, av, ":do:I:")) != EOF) { 244#else 245 while((ch = getopt(ac, av, ":o:I:")) != EOF) { 246#endif 247 switch (ch) 248 { 249#ifdef COLLATE_DEBUG 250 case 'd': 251 debug++; 252 break; 253#endif 254 case 'o': 255 out_file = optarg; 256 break; 257 258 case 'I': 259 strlcpy(map_name, optarg, sizeof(map_name)); 260 break; 261 262 default: 263 usage(); 264 } 265 } 266 ac -= optind; 267 av += optind; 268 if(ac > 0) { 269 if((yyin = fopen(*av, "r")) == 0) 270 err(EX_UNAVAILABLE, "can't open source file %s", *av); 271 } 272 for(ch = 0; ch <= UCHAR_MAX; ch++) 273 __collate_substitute_table[ch][0] = ch; 274 yyparse(); 275 return 0; 276} 277 278static void 279usage() 280{ 281 fprintf(stderr, "usage: colldef [-o out_file] [-I map_dir] [filename]\n"); 282 exit(EX_USAGE); 283} 284
|
281void yyerror(char *fmt, ...)
| 285void 286yyerror(const char *fmt, ...)
|
282{ 283 va_list ap; 284 char msg[128]; 285 286 va_start(ap, fmt); 287 vsnprintf(msg, sizeof(msg), fmt, ap); 288 va_end(ap); 289 errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no); 290} 291 292#ifdef COLLATE_DEBUG
| 287{ 288 va_list ap; 289 char msg[128]; 290 291 va_start(ap, fmt); 292 vsnprintf(msg, sizeof(msg), fmt, ap); 293 va_end(ap); 294 errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no); 295} 296 297#ifdef COLLATE_DEBUG
|
293void 294collate_print_tables()
| 298static void 299collate_print_tables(void)
|
295{ 296 int i; 297 struct __collate_st_chain_pri *p2; 298 299 printf("Substitute table:\n"); 300 for (i = 0; i < UCHAR_MAX + 1; i++) 301 if (i != *__collate_substitute_table[i]) 302 printf("\t'%c' --> \"%s\"\n", i, 303 __collate_substitute_table[i]); 304 printf("Chain priority table:\n"); 305 for (p2 = __collate_chain_pri_table; p2->str[0]; p2++) 306 printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec); 307 printf("Char priority table:\n"); 308 for (i = 0; i < UCHAR_MAX + 1; i++) 309 printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, 310 __collate_char_pri_table[i].sec); 311} 312#endif
| 300{ 301 int i; 302 struct __collate_st_chain_pri *p2; 303 304 printf("Substitute table:\n"); 305 for (i = 0; i < UCHAR_MAX + 1; i++) 306 if (i != *__collate_substitute_table[i]) 307 printf("\t'%c' --> \"%s\"\n", i, 308 __collate_substitute_table[i]); 309 printf("Chain priority table:\n"); 310 for (p2 = __collate_chain_pri_table; p2->str[0]; p2++) 311 printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec); 312 printf("Char priority table:\n"); 313 for (i = 0; i < UCHAR_MAX + 1; i++) 314 printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, 315 __collate_char_pri_table[i].sec); 316} 317#endif
|