source: trunk/minix/commands/ash/mksyntax.c@ 11

Last change on this file since 11 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 8.8 KB
Line 
1/*-
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38char copyright[] =
39"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
40 All rights reserved.\n";
41#endif /* not lint */
42
43#ifndef lint
44static char sccsid[] = "@(#)mksyntax.c 5.2 (Berkeley) 3/8/91";
45#endif /* not lint */
46
47/*
48 * This program creates syntax.h and syntax.c.
49 */
50
51#include <stdio.h>
52#include "parser.h"
53
54
55struct synclass {
56 char *name;
57 char *comment;
58};
59
60/* Syntax classes */
61struct synclass synclass[] = {
62 "CWORD", "character is nothing special",
63 "CNL", "newline character",
64 "CBACK", "a backslash character",
65 "CSQUOTE", "single quote",
66 "CDQUOTE", "double quote",
67 "CENDQUOTE", "a terminating quote",
68 "CBQUOTE", "backwards single quote",
69 "CVAR", "a dollar sign",
70 "CENDVAR", "a '}' character",
71 "CEOF", "end of file",
72 "CCTL", "like CWORD, except it must be escaped",
73 "CSPCL", "these terminate a word",
74 NULL, NULL
75};
76
77
78/*
79 * Syntax classes for is_ functions. Warning: if you add new classes
80 * you may have to change the definition of the is_in_name macro.
81 */
82struct synclass is_entry[] = {
83 "ISDIGIT", "a digit",
84 "ISUPPER", "an upper case letter",
85 "ISLOWER", "a lower case letter",
86 "ISUNDER", "an underscore",
87 "ISSPECL", "the name of a special parameter",
88 NULL, NULL,
89};
90
91char writer[] = "\
92/*\n\
93 * This file was generated by the mksyntax program.\n\
94 */\n\
95\n";
96
97
98FILE *cfile;
99FILE *hfile;
100char *syntax[513];
101int base;
102int size; /* number of values which a char variable can have */
103int nbits; /* number of bits in a character */
104int digit_contig; /* true if digits are contiguous */
105
106
107main() {
108 char c;
109 char d;
110 int sign;
111 int i;
112 char buf[80];
113 int pos;
114 static char digit[] = "0123456789";
115
116 /* Create output files */
117 if ((cfile = fopen("syntax.c", "w")) == NULL) {
118 perror("syntax.c");
119 exit(2);
120 }
121 if ((hfile = fopen("syntax.h", "w")) == NULL) {
122 perror("syntax.h");
123 exit(2);
124 }
125 fputs(writer, hfile);
126 fputs(writer, cfile);
127
128 /* Determine the characteristics of chars. */
129 c = -1;
130 if (c < 0)
131 sign = 1;
132 else
133 sign = 0;
134 for (nbits = 1 ; ; nbits++) {
135 d = (1 << nbits) - 1;
136 if (d == c)
137 break;
138 }
139 printf("%s %d bit chars\n", sign? "signed" : "unsigned", nbits);
140 if (nbits > 9) {
141 fputs("Characters can't have more than 9 bits\n", stderr);
142 exit(2);
143 }
144 size = (1 << nbits) + 1;
145 base = 1;
146 if (sign)
147 base += 1 << (nbits - 1);
148 digit_contig = 1;
149 for (i = 0 ; i < 10 ; i++) {
150 if (digit[i] != '0' + i)
151 digit_contig = 0;
152 }
153
154 fputs("#include <sys/cdefs.h>\n", hfile);
155
156 /* Generate the #define statements in the header file */
157 fputs("/* Syntax classes */\n", hfile);
158 for (i = 0 ; synclass[i].name ; i++) {
159 sprintf(buf, "#define %s %d", synclass[i].name, i);
160 fputs(buf, hfile);
161 for (pos = strlen(buf) ; pos < 32 ; pos = pos + 8 &~ 07)
162 putc('\t', hfile);
163 fprintf(hfile, "/* %s */\n", synclass[i].comment);
164 }
165 putc('\n', hfile);
166 fputs("/* Syntax classes for is_ functions */\n", hfile);
167 for (i = 0 ; is_entry[i].name ; i++) {
168 sprintf(buf, "#define %s %#o", is_entry[i].name, 1 << i);
169 fputs(buf, hfile);
170 for (pos = strlen(buf) ; pos < 32 ; pos = pos + 8 &~ 07)
171 putc('\t', hfile);
172 fprintf(hfile, "/* %s */\n", is_entry[i].comment);
173 }
174 putc('\n', hfile);
175 fprintf(hfile, "#define SYNBASE %d\n", base);
176 fprintf(hfile, "#define PEOF %d\n\n", -base);
177 putc('\n', hfile);
178 fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile);
179 fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile);
180 fputs("#define SQSYNTAX (sqsyntax + SYNBASE)\n", hfile);
181 putc('\n', hfile);
182 output_type_macros(); /* is_digit, etc. */
183 putc('\n', hfile);
184
185 /* Generate the syntax tables. */
186 fputs("#include \"shell.h\"\n", cfile);
187 fputs("#include \"syntax.h\"\n\n", cfile);
188 init();
189 fputs("/* syntax table used when not in quotes */\n", cfile);
190 add("\n", "CNL");
191 add("\\", "CBACK");
192 add("'", "CSQUOTE");
193 add("\"", "CDQUOTE");
194 add("`", "CBQUOTE");
195 add("$", "CVAR");
196 add("}", "CENDVAR");
197 add("<>();&| \t", "CSPCL");
198 print("basesyntax");
199 init();
200 fputs("\n/* syntax table used when in double quotes */\n", cfile);
201 add("\n", "CNL");
202 add("\\", "CBACK");
203 add("\"", "CENDQUOTE");
204 add("`", "CBQUOTE");
205 add("$", "CVAR");
206 add("}", "CENDVAR");
207 add("!*?[=", "CCTL");
208 print("dqsyntax");
209 init();
210 fputs("\n/* syntax table used when in single quotes */\n", cfile);
211 add("\n", "CNL");
212 add("'", "CENDQUOTE");
213 add("!*?[=", "CCTL");
214 print("sqsyntax");
215 filltable("0");
216 fputs("\n/* character classification table */\n", cfile);
217 add("0123456789", "ISDIGIT");
218 add("abcdefghijklmnopqrstucvwxyz", "ISLOWER");
219 add("ABCDEFGHIJKLMNOPQRSTUCVWXYZ", "ISUPPER");
220 add("_", "ISUNDER");
221 add("#?$!-*@", "ISSPECL");
222 print("is_type");
223 if (! digit_contig)
224 digit_convert();
225 exit(0);
226}
227
228
229
230/*
231 * Clear the syntax table.
232 */
233
234filltable(dftval)
235 char *dftval;
236 {
237 int i;
238
239 for (i = 0 ; i < size ; i++)
240 syntax[i] = dftval;
241}
242
243
244/*
245 * Initialize the syntax table with default values.
246 */
247
248init() {
249 filltable("CWORD");
250 syntax[0] = "CEOF";
251 syntax[base + CTLESC] = "CCTL";
252 syntax[base + CTLVAR] = "CCTL";
253 syntax[base + CTLENDVAR] = "CCTL";
254 syntax[base + CTLBACKQ] = "CCTL";
255 syntax[base + CTLBACKQ + CTLQUOTE] = "CCTL";
256}
257
258
259/*
260 * Add entries to the syntax table.
261 */
262
263add(p, type)
264 char *p, *type;
265 {
266 while (*p)
267 syntax[*p++ + base] = type;
268}
269
270
271
272/*
273 * Output the syntax table.
274 */
275
276print(name)
277 char *name;
278 {
279 int i;
280 int col;
281
282 fprintf(hfile, "extern const char %s[];\n", name);
283 fprintf(cfile, "const char %s[%d] = {\n", name, size);
284 col = 0;
285 for (i = 0 ; i < size ; i++) {
286 if (i == 0) {
287 fputs(" ", cfile);
288 } else if ((i & 03) == 0) {
289 fputs(",\n ", cfile);
290 col = 0;
291 } else {
292 putc(',', cfile);
293 while (++col < 9 * (i & 03))
294 putc(' ', cfile);
295 }
296 fputs(syntax[i], cfile);
297 col += strlen(syntax[i]);
298 }
299 fputs("\n};\n", cfile);
300}
301
302
303
304/*
305 * Output character classification macros (e.g. is_digit). If digits are
306 * contiguous, we can test for them quickly.
307 */
308
309char *macro[] = {
310 "#define is_digit(c)\t((is_type+SYNBASE)[c] & ISDIGIT)",
311 "#define is_alpha(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER))",
312 "#define is_name(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER|ISUNDER))",
313 "#define is_in_name(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER|ISUNDER|ISDIGIT))",
314 "#define is_special(c)\t((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))",
315 NULL
316};
317
318output_type_macros() {
319 char **pp;
320
321 if (digit_contig)
322 macro[0] = "#define is_digit(c)\t((unsigned)((c) - '0') <= 9)";
323 for (pp = macro ; *pp ; pp++)
324 fprintf(hfile, "%s\n", *pp);
325 if (digit_contig)
326 fputs("#define digit_val(c)\t((c) - '0')\n", hfile);
327 else
328 fputs("#define digit_val(c)\t(digit_value[c])\n", hfile);
329}
330
331
332
333/*
334 * Output digit conversion table (if digits are not contiguous).
335 */
336
337digit_convert() {
338 int maxdigit;
339 static char digit[] = "0123456789";
340 char *p;
341 int i;
342
343 maxdigit = 0;
344 for (p = digit ; *p ; p++)
345 if (*p > maxdigit)
346 maxdigit = *p;
347 fputs("extern const char digit_value[];\n", hfile);
348 fputs("\n\nconst char digit_value[] = {\n", cfile);
349 for (i = 0 ; i <= maxdigit ; i++) {
350 for (p = digit ; *p && *p != i ; p++);
351 if (*p == '\0')
352 p = digit;
353 fprintf(cfile, " %d,\n", p - digit);
354 }
355 fputs("};\n", cfile);
356}
Note: See TracBrowser for help on using the repository browser.