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

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

Initial commit of ash shell.
It cannot be compiled yet.

  • Property mode set to 100644
File size: 11.5 KB
Line 
1/* $NetBSD: mknodes.c,v 1.18 2000/07/27 04:06:49 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[] = "@(#)mknodes.c 8.2 (Berkeley) 5/4/95";
48#else
49static const char rcsid[] =
50 "$NetBSD: mknodes.c,v 1.18 2000/07/27 04:06:49 cgd Exp $";
51#endif
52#endif /* not lint */
53
54/*
55 * This program reads the nodetypes file and nodes.c.pat file. It generates
56 * the files nodes.h and nodes.c.
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62#ifdef __STDC__
63#include <stdarg.h>
64#else
65#include <varargs.h>
66#endif
67
68
69#define MAXTYPES 50 /* max number of node types */
70#define MAXFIELDS 20 /* max fields in a structure */
71#define BUFLEN 100 /* size of character buffers */
72
73/* field types */
74#define T_NODE 1 /* union node *field */
75#define T_NODELIST 2 /* struct nodelist *field */
76#define T_STRING 3
77#define T_INT 4 /* int field */
78#define T_OTHER 5 /* other */
79#define T_TEMP 6 /* don't copy this field */
80
81
82struct field { /* a structure field */
83 char *name; /* name of field */
84 int type; /* type of field */
85 char *decl; /* declaration of field */
86};
87
88
89struct str { /* struct representing a node structure */
90 char *tag; /* structure tag */
91 int nfields; /* number of fields in the structure */
92 struct field field[MAXFIELDS]; /* the fields of the structure */
93 int done; /* set if fully parsed */
94};
95
96
97static int ntypes; /* number of node types */
98static char *nodename[MAXTYPES]; /* names of the nodes */
99static struct str *nodestr[MAXTYPES]; /* type of structure used by the node */
100static int nstr; /* number of structures */
101static struct str str[MAXTYPES]; /* the structures */
102static struct str *curstr; /* current structure */
103static FILE *infp;
104static char line[1024];
105static int linno;
106static char *linep;
107
108static void parsenode(void);
109static void parsefield(void);
110static void output(char *);
111static void outsizes(FILE *);
112static void outfunc(FILE *, int);
113static void indent(int, FILE *);
114static int nextfield(char *);
115static void skipbl(void);
116static int readline(void);
117static void error(const char *, ...);
118static char *savestr(const char *);
119int main(int, char **);
120
121
122int
123main(argc, argv)
124 int argc;
125 char **argv;
126{
127
128 /*
129 * some versions of linux complain: initializer element is not
130 * constant if this is done at compile time.
131 */
132 infp = stdin;
133
134 if (argc != 3)
135 error("usage: mknodes file");
136 if ((infp = fopen(argv[1], "r")) == NULL)
137 error("Can't open %s", argv[1]);
138 while (readline()) {
139 if (line[0] == ' ' || line[0] == '\t')
140 parsefield();
141 else if (line[0] != '\0')
142 parsenode();
143 }
144 output(argv[2]);
145 exit(0);
146 /* NOTREACHED */
147}
148
149
150
151static void
152parsenode()
153{
154 char name[BUFLEN];
155 char tag[BUFLEN];
156 struct str *sp;
157
158 if (curstr && curstr->nfields > 0)
159 curstr->done = 1;
160 nextfield(name);
161 if (! nextfield(tag))
162 error("Tag expected");
163 if (*linep != '\0')
164 error("Garbage at end of line");
165 nodename[ntypes] = savestr(name);
166 for (sp = str ; sp < str + nstr ; sp++) {
167 if (strcmp(sp->tag, tag) == 0)
168 break;
169 }
170 if (sp >= str + nstr) {
171 sp->tag = savestr(tag);
172 sp->nfields = 0;
173 curstr = sp;
174 nstr++;
175 }
176 nodestr[ntypes] = sp;
177 ntypes++;
178}
179
180
181static void
182parsefield()
183{
184 char name[BUFLEN];
185 char type[BUFLEN];
186 char decl[2 * BUFLEN];
187 struct field *fp;
188
189 if (curstr == NULL || curstr->done)
190 error("No current structure to add field to");
191 if (! nextfield(name))
192 error("No field name");
193 if (! nextfield(type))
194 error("No field type");
195 fp = &curstr->field[curstr->nfields];
196 fp->name = savestr(name);
197 if (strcmp(type, "nodeptr") == 0) {
198 fp->type = T_NODE;
199 sprintf(decl, "union node *%s", name);
200 } else if (strcmp(type, "nodelist") == 0) {
201 fp->type = T_NODELIST;
202 sprintf(decl, "struct nodelist *%s", name);
203 } else if (strcmp(type, "string") == 0) {
204 fp->type = T_STRING;
205 sprintf(decl, "char *%s", name);
206 } else if (strcmp(type, "int") == 0) {
207 fp->type = T_INT;
208 sprintf(decl, "int %s", name);
209 } else if (strcmp(type, "other") == 0) {
210 fp->type = T_OTHER;
211 } else if (strcmp(type, "temp") == 0) {
212 fp->type = T_TEMP;
213 } else {
214 error("Unknown type %s", type);
215 }
216 if (fp->type == T_OTHER || fp->type == T_TEMP) {
217 skipbl();
218 fp->decl = savestr(linep);
219 } else {
220 if (*linep)
221 error("Garbage at end of line");
222 fp->decl = savestr(decl);
223 }
224 curstr->nfields++;
225}
226
227
228char writer[] = "\
229/*\n\
230 * This file was generated by the mknodes program.\n\
231 */\n\
232\n";
233
234static void
235output(file)
236 char *file;
237{
238 FILE *hfile;
239 FILE *cfile;
240 FILE *patfile;
241 int i;
242 struct str *sp;
243 struct field *fp;
244 char *p;
245
246 if ((patfile = fopen(file, "r")) == NULL)
247 error("Can't open %s", file);
248 if ((hfile = fopen("nodes.h", "w")) == NULL)
249 error("Can't create nodes.h");
250 if ((cfile = fopen("nodes.c", "w")) == NULL)
251 error("Can't create nodes.c");
252 fputs(writer, hfile);
253 for (i = 0 ; i < ntypes ; i++)
254 fprintf(hfile, "#define %s %d\n", nodename[i], i);
255 fputs("\n\n\n", hfile);
256 for (sp = str ; sp < &str[nstr] ; sp++) {
257 fprintf(hfile, "struct %s {\n", sp->tag);
258 for (i = sp->nfields, fp = sp->field ; --i >= 0 ; fp++) {
259 fprintf(hfile, " %s;\n", fp->decl);
260 }
261 fputs("};\n\n\n", hfile);
262 }
263 fputs("union node {\n", hfile);
264 fprintf(hfile, " int type;\n");
265 for (sp = str ; sp < &str[nstr] ; sp++) {
266 fprintf(hfile, " struct %s %s;\n", sp->tag, sp->tag);
267 }
268 fputs("};\n\n\n", hfile);
269 fputs("struct nodelist {\n", hfile);
270 fputs("\tstruct nodelist *next;\n", hfile);
271 fputs("\tunion node *n;\n", hfile);
272 fputs("};\n\n\n", hfile);
273 fputs("#ifdef __STDC__\n", hfile);
274 fputs("union node *copyfunc(union node *);\n", hfile);
275 fputs("void freefunc(union node *);\n", hfile);
276 fputs("#else\n", hfile);
277 fputs("union node *copyfunc();\n", hfile);
278 fputs("void freefunc();\n", hfile);
279 fputs("#endif\n", hfile);
280
281 fputs(writer, cfile);
282 while (fgets(line, sizeof line, patfile) != NULL) {
283 for (p = line ; *p == ' ' || *p == '\t' ; p++);
284 if (strcmp(p, "%SIZES\n") == 0)
285 outsizes(cfile);
286 else if (strcmp(p, "%CALCSIZE\n") == 0)
287 outfunc(cfile, 1);
288 else if (strcmp(p, "%COPY\n") == 0)
289 outfunc(cfile, 0);
290 else
291 fputs(line, cfile);
292 }
293}
294
295
296
297static void
298outsizes(cfile)
299 FILE *cfile;
300{
301 int i;
302
303 fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes);
304 for (i = 0 ; i < ntypes ; i++) {
305 fprintf(cfile, " ALIGN(sizeof (struct %s)),\n", nodestr[i]->tag);
306 }
307 fprintf(cfile, "};\n");
308}
309
310
311static void
312outfunc(cfile, calcsize)
313 FILE *cfile;
314 int calcsize;
315{
316 struct str *sp;
317 struct field *fp;
318 int i;
319
320 fputs(" if (n == NULL)\n", cfile);
321 if (calcsize)
322 fputs(" return;\n", cfile);
323 else
324 fputs(" return NULL;\n", cfile);
325 if (calcsize)
326 fputs(" funcblocksize += nodesize[n->type];\n", cfile);
327 else {
328 fputs(" new = funcblock;\n", cfile);
329 fputs(" funcblock = (char *) funcblock + nodesize[n->type];\n", cfile);
330 }
331 fputs(" switch (n->type) {\n", cfile);
332 for (sp = str ; sp < &str[nstr] ; sp++) {
333 for (i = 0 ; i < ntypes ; i++) {
334 if (nodestr[i] == sp)
335 fprintf(cfile, " case %s:\n", nodename[i]);
336 }
337 for (i = sp->nfields ; --i >= 1 ; ) {
338 fp = &sp->field[i];
339 switch (fp->type) {
340 case T_NODE:
341 if (calcsize) {
342 indent(12, cfile);
343 fprintf(cfile, "calcsize(n->%s.%s);\n",
344 sp->tag, fp->name);
345 } else {
346 indent(12, cfile);
347 fprintf(cfile, "new->%s.%s = copynode(n->%s.%s);\n",
348 sp->tag, fp->name, sp->tag, fp->name);
349 }
350 break;
351 case T_NODELIST:
352 if (calcsize) {
353 indent(12, cfile);
354 fprintf(cfile, "sizenodelist(n->%s.%s);\n",
355 sp->tag, fp->name);
356 } else {
357 indent(12, cfile);
358 fprintf(cfile, "new->%s.%s = copynodelist(n->%s.%s);\n",
359 sp->tag, fp->name, sp->tag, fp->name);
360 }
361 break;
362 case T_STRING:
363 if (calcsize) {
364 indent(12, cfile);
365 fprintf(cfile, "funcstringsize += strlen(n->%s.%s) + 1;\n",
366 sp->tag, fp->name);
367 } else {
368 indent(12, cfile);
369 fprintf(cfile, "new->%s.%s = nodesavestr(n->%s.%s);\n",
370 sp->tag, fp->name, sp->tag, fp->name);
371 }
372 break;
373 case T_INT:
374 case T_OTHER:
375 if (! calcsize) {
376 indent(12, cfile);
377 fprintf(cfile, "new->%s.%s = n->%s.%s;\n",
378 sp->tag, fp->name, sp->tag, fp->name);
379 }
380 break;
381 }
382 }
383 indent(12, cfile);
384 fputs("break;\n", cfile);
385 }
386 fputs(" };\n", cfile);
387 if (! calcsize)
388 fputs(" new->type = n->type;\n", cfile);
389}
390
391
392static void
393indent(amount, fp)
394 int amount;
395 FILE *fp;
396{
397 while (amount >= 8) {
398 putc('\t', fp);
399 amount -= 8;
400 }
401 while (--amount >= 0) {
402 putc(' ', fp);
403 }
404}
405
406
407static int
408nextfield(buf)
409 char *buf;
410{
411 char *p, *q;
412
413 p = linep;
414 while (*p == ' ' || *p == '\t')
415 p++;
416 q = buf;
417 while (*p != ' ' && *p != '\t' && *p != '\0')
418 *q++ = *p++;
419 *q = '\0';
420 linep = p;
421 return (q > buf);
422}
423
424
425static void
426skipbl()
427{
428 while (*linep == ' ' || *linep == '\t')
429 linep++;
430}
431
432
433static int
434readline()
435{
436 char *p;
437
438 if (fgets(line, 1024, infp) == NULL)
439 return 0;
440 for (p = line ; *p != '#' && *p != '\n' && *p != '\0' ; p++);
441 while (p > line && (p[-1] == ' ' || p[-1] == '\t'))
442 p--;
443 *p = '\0';
444 linep = line;
445 linno++;
446 if (p - line > BUFLEN)
447 error("Line too long");
448 return 1;
449}
450
451
452
453static void
454#ifdef __STDC__
455error(const char *msg, ...)
456#else
457error(va_alist)
458 va_dcl
459#endif
460{
461 va_list va;
462#ifdef __STDC__
463 va_start(va, msg);
464#else
465 char *msg;
466 va_start(va);
467 msg = va_arg(va, char *);
468#endif
469
470 (void) fprintf(stderr, "line %d: ", linno);
471 (void) vfprintf(stderr, msg, va);
472 (void) fputc('\n', stderr);
473
474 va_end(va);
475
476 exit(2);
477 /* NOTREACHED */
478}
479
480
481
482static char *
483savestr(s)
484 const char *s;
485{
486 char *p;
487
488 if ((p = malloc(strlen(s) + 1)) == NULL)
489 error("Out of space");
490 (void) strcpy(p, s);
491 return p;
492}
Note: See TracBrowser for help on using the repository browser.