source: mainline/uspace/app/ash/tools/mksyntax.c@ 8ccd2ea

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8ccd2ea was 6a4aa56, checked in by Josef Cejka <malyzelenyhnus@…>, 17 years ago

Ash: fixed recursive Makefile.

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