Annotation of /trunk/mkinitrd-magellan/klibc/usr/dash/mksyntax.c
Parent Directory | Revision Log
Revision 1122 -
(hide annotations)
(download)
Wed Aug 18 21:11:40 2010 UTC (13 years, 9 months ago) by niro
File MIME type: text/plain
File size: 8258 byte(s)
Wed Aug 18 21:11:40 2010 UTC (13 years, 9 months ago) by niro
File MIME type: text/plain
File size: 8258 byte(s)
-updated to klibc-1.5.19
1 | niro | 532 | /*- |
2 | * Copyright (c) 1991, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * Copyright (c) 1997-2005 | ||
5 | * Herbert Xu <herbert@gondor.apana.org.au>. All rights reserved. | ||
6 | * | ||
7 | * This code is derived from software contributed to Berkeley by | ||
8 | * Kenneth Almquist. | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * 3. Neither the name of the University nor the names of its contributors | ||
19 | * may be used to endorse or promote products derived from this software | ||
20 | * without specific prior written permission. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | * SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | /* | ||
36 | * This program creates syntax.h and syntax.c. | ||
37 | */ | ||
38 | |||
39 | #include <stdio.h> | ||
40 | #include <stdlib.h> | ||
41 | #include <string.h> | ||
42 | #include <sys/types.h> | ||
43 | #include "parser.h" | ||
44 | |||
45 | |||
46 | struct synclass { | ||
47 | char *name; | ||
48 | char *comment; | ||
49 | }; | ||
50 | |||
51 | /* Syntax classes */ | ||
52 | struct synclass synclass[] = { | ||
53 | { "CWORD", "character is nothing special" }, | ||
54 | { "CNL", "newline character" }, | ||
55 | { "CBACK", "a backslash character" }, | ||
56 | { "CSQUOTE", "single quote" }, | ||
57 | { "CDQUOTE", "double quote" }, | ||
58 | { "CENDQUOTE", "a terminating quote" }, | ||
59 | { "CBQUOTE", "backwards single quote" }, | ||
60 | { "CVAR", "a dollar sign" }, | ||
61 | { "CENDVAR", "a '}' character" }, | ||
62 | { "CLP", "a left paren in arithmetic" }, | ||
63 | { "CRP", "a right paren in arithmetic" }, | ||
64 | { "CEOF", "end of file" }, | ||
65 | { "CCTL", "like CWORD, except it must be escaped" }, | ||
66 | { "CSPCL", "these terminate a word" }, | ||
67 | { "CIGN", "character should be ignored" }, | ||
68 | { NULL, NULL } | ||
69 | }; | ||
70 | |||
71 | |||
72 | /* | ||
73 | * Syntax classes for is_ functions. Warning: if you add new classes | ||
74 | * you may have to change the definition of the is_in_name macro. | ||
75 | */ | ||
76 | struct synclass is_entry[] = { | ||
77 | { "ISDIGIT", "a digit" }, | ||
78 | { "ISUPPER", "an upper case letter" }, | ||
79 | { "ISLOWER", "a lower case letter" }, | ||
80 | { "ISUNDER", "an underscore" }, | ||
81 | { "ISSPECL", "the name of a special parameter" }, | ||
82 | { NULL, NULL } | ||
83 | }; | ||
84 | |||
85 | static char writer[] = "\ | ||
86 | /*\n\ | ||
87 | * This file was generated by the mksyntax program.\n\ | ||
88 | */\n\ | ||
89 | \n"; | ||
90 | |||
91 | |||
92 | static FILE *cfile; | ||
93 | static FILE *hfile; | ||
94 | static char *syntax[513]; | ||
95 | |||
96 | static void filltable(char *); | ||
97 | static void init(void); | ||
98 | static void add(char *, char *); | ||
99 | static void print(char *); | ||
100 | static void output_type_macros(void); | ||
101 | int main(int, char **); | ||
102 | |||
103 | int | ||
104 | main(int argc, char **argv) | ||
105 | { | ||
106 | int i; | ||
107 | char buf[80]; | ||
108 | int pos; | ||
109 | |||
110 | /* Create output files */ | ||
111 | if ((cfile = fopen("syntax.c", "w")) == NULL) { | ||
112 | perror("syntax.c"); | ||
113 | exit(2); | ||
114 | } | ||
115 | if ((hfile = fopen("syntax.h", "w")) == NULL) { | ||
116 | perror("syntax.h"); | ||
117 | exit(2); | ||
118 | } | ||
119 | fputs(writer, hfile); | ||
120 | fputs(writer, cfile); | ||
121 | |||
122 | fputs("#include <ctype.h>\n", hfile); | ||
123 | fputs("\n", hfile); | ||
124 | fputs("#ifdef CEOF\n", hfile); | ||
125 | fputs("#undef CEOF\n", hfile); | ||
126 | fputs("#endif\n", hfile); | ||
127 | fputs("\n", hfile); | ||
128 | |||
129 | /* Generate the #define statements in the header file */ | ||
130 | fputs("/* Syntax classes */\n", hfile); | ||
131 | for (i = 0 ; synclass[i].name ; i++) { | ||
132 | sprintf(buf, "#define %s %d", synclass[i].name, i); | ||
133 | fputs(buf, hfile); | ||
134 | for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07) | ||
135 | putc('\t', hfile); | ||
136 | fprintf(hfile, "/* %s */\n", synclass[i].comment); | ||
137 | } | ||
138 | putc('\n', hfile); | ||
139 | fputs("/* Syntax classes for is_ functions */\n", hfile); | ||
140 | for (i = 0 ; is_entry[i].name ; i++) { | ||
141 | sprintf(buf, "#define %s %#o", is_entry[i].name, 1 << i); | ||
142 | fputs(buf, hfile); | ||
143 | for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07) | ||
144 | putc('\t', hfile); | ||
145 | fprintf(hfile, "/* %s */\n", is_entry[i].comment); | ||
146 | } | ||
147 | putc('\n', hfile); | ||
148 | fprintf(hfile, "#define SYNBASE %d\n", 130); | ||
149 | fprintf(hfile, "#define PEOF %d\n\n", -130); | ||
150 | fprintf(hfile, "#define PEOA %d\n\n", -129); | ||
151 | putc('\n', hfile); | ||
152 | fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile); | ||
153 | fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile); | ||
154 | fputs("#define SQSYNTAX (sqsyntax + SYNBASE)\n", hfile); | ||
155 | fputs("#define ARISYNTAX (arisyntax + SYNBASE)\n", hfile); | ||
156 | putc('\n', hfile); | ||
157 | output_type_macros(); /* is_digit, etc. */ | ||
158 | putc('\n', hfile); | ||
159 | |||
160 | /* Generate the syntax tables. */ | ||
161 | fputs("#include \"shell.h\"\n", cfile); | ||
162 | fputs("#include \"syntax.h\"\n\n", cfile); | ||
163 | init(); | ||
164 | fputs("/* syntax table used when not in quotes */\n", cfile); | ||
165 | add("\n", "CNL"); | ||
166 | add("\\", "CBACK"); | ||
167 | add("'", "CSQUOTE"); | ||
168 | add("\"", "CDQUOTE"); | ||
169 | add("`", "CBQUOTE"); | ||
170 | add("$", "CVAR"); | ||
171 | add("}", "CENDVAR"); | ||
172 | add("<>();&| \t", "CSPCL"); | ||
173 | syntax[1] = "CSPCL"; | ||
174 | print("basesyntax"); | ||
175 | init(); | ||
176 | fputs("\n/* syntax table used when in double quotes */\n", cfile); | ||
177 | add("\n", "CNL"); | ||
178 | add("\\", "CBACK"); | ||
179 | add("\"", "CENDQUOTE"); | ||
180 | add("`", "CBQUOTE"); | ||
181 | add("$", "CVAR"); | ||
182 | add("}", "CENDVAR"); | ||
183 | /* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */ | ||
184 | add("!*?[=~:/-]", "CCTL"); | ||
185 | print("dqsyntax"); | ||
186 | init(); | ||
187 | fputs("\n/* syntax table used when in single quotes */\n", cfile); | ||
188 | add("\n", "CNL"); | ||
189 | add("'", "CENDQUOTE"); | ||
190 | /* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */ | ||
191 | add("!*?[=~:/-]\\", "CCTL"); | ||
192 | print("sqsyntax"); | ||
193 | init(); | ||
194 | fputs("\n/* syntax table used when in arithmetic */\n", cfile); | ||
195 | add("\n", "CNL"); | ||
196 | add("\\", "CBACK"); | ||
197 | add("`", "CBQUOTE"); | ||
198 | add("$", "CVAR"); | ||
199 | add("}", "CENDVAR"); | ||
200 | add("(", "CLP"); | ||
201 | add(")", "CRP"); | ||
202 | print("arisyntax"); | ||
203 | filltable("0"); | ||
204 | fputs("\n/* character classification table */\n", cfile); | ||
205 | add("0123456789", "ISDIGIT"); | ||
206 | add("abcdefghijklmnopqrstucvwxyz", "ISLOWER"); | ||
207 | add("ABCDEFGHIJKLMNOPQRSTUCVWXYZ", "ISUPPER"); | ||
208 | add("_", "ISUNDER"); | ||
209 | add("#?$!-*@", "ISSPECL"); | ||
210 | print("is_type"); | ||
211 | exit(0); | ||
212 | /* NOTREACHED */ | ||
213 | } | ||
214 | |||
215 | |||
216 | |||
217 | /* | ||
218 | * Clear the syntax table. | ||
219 | */ | ||
220 | |||
221 | static void | ||
222 | filltable(char *dftval) | ||
223 | { | ||
224 | int i; | ||
225 | |||
226 | niro | 1122 | for (i = 0 ; i < 258; i++) |
227 | niro | 532 | syntax[i] = dftval; |
228 | } | ||
229 | |||
230 | |||
231 | /* | ||
232 | * Initialize the syntax table with default values. | ||
233 | */ | ||
234 | |||
235 | static void | ||
236 | init(void) | ||
237 | { | ||
238 | int ctl; | ||
239 | |||
240 | filltable("CWORD"); | ||
241 | syntax[0] = "CEOF"; | ||
242 | syntax[1] = "CIGN"; | ||
243 | for (ctl = CTL_FIRST; ctl <= CTL_LAST; ctl++ ) | ||
244 | syntax[130 + ctl] = "CCTL"; | ||
245 | } | ||
246 | |||
247 | |||
248 | /* | ||
249 | * Add entries to the syntax table. | ||
250 | */ | ||
251 | |||
252 | static void | ||
253 | add(char *p, char *type) | ||
254 | { | ||
255 | while (*p) | ||
256 | syntax[(signed char)*p++ + 130] = type; | ||
257 | } | ||
258 | |||
259 | |||
260 | |||
261 | /* | ||
262 | * Output the syntax table. | ||
263 | */ | ||
264 | |||
265 | static void | ||
266 | print(char *name) | ||
267 | { | ||
268 | int i; | ||
269 | int col; | ||
270 | |||
271 | fprintf(hfile, "extern const char %s[];\n", name); | ||
272 | niro | 1122 | fprintf(cfile, "const char %s[] = {\n", name); |
273 | niro | 532 | col = 0; |
274 | niro | 1122 | for (i = 0 ; i < 258; i++) { |
275 | niro | 532 | if (i == 0) { |
276 | fputs(" ", cfile); | ||
277 | } else if ((i & 03) == 0) { | ||
278 | fputs(",\n ", cfile); | ||
279 | col = 0; | ||
280 | } else { | ||
281 | putc(',', cfile); | ||
282 | while (++col < 9 * (i & 03)) | ||
283 | putc(' ', cfile); | ||
284 | } | ||
285 | fputs(syntax[i], cfile); | ||
286 | col += strlen(syntax[i]); | ||
287 | } | ||
288 | fputs("\n};\n", cfile); | ||
289 | } | ||
290 | |||
291 | |||
292 | |||
293 | /* | ||
294 | * Output character classification macros (e.g. is_digit). If digits are | ||
295 | * contiguous, we can test for them quickly. | ||
296 | */ | ||
297 | |||
298 | static char *macro[] = { | ||
299 | "#define is_digit(c)\t((unsigned)((c) - '0') <= 9)\n", | ||
300 | "#define is_alpha(c)\tisalpha((unsigned char)(c))\n", | ||
301 | "#define is_name(c)\t((c) == '_' || isalpha((unsigned char)(c)))\n", | ||
302 | "#define is_in_name(c)\t((c) == '_' || isalnum((unsigned char)(c)))\n", | ||
303 | "#define is_special(c)\t((is_type+SYNBASE)[(signed char)(c)] & (ISSPECL|ISDIGIT))\n", | ||
304 | NULL | ||
305 | }; | ||
306 | |||
307 | static void | ||
308 | output_type_macros(void) | ||
309 | { | ||
310 | char **pp; | ||
311 | |||
312 | for (pp = macro ; *pp ; pp++) | ||
313 | fputs(*pp, hfile); | ||
314 | fputs("#define digit_val(c)\t((c) - '0')\n", hfile); | ||
315 | } |