xref: /csrg-svn/bin/sh/mknodes.c (revision 69272)
147131Sbostic /*-
260698Sbostic  * Copyright (c) 1991, 1993
360698Sbostic  *	The Regents of the University of California.  All rights reserved.
447131Sbostic  *
547131Sbostic  * This code is derived from software contributed to Berkeley by
647131Sbostic  * Kenneth Almquist.
747131Sbostic  *
847131Sbostic  * %sccs.include.redist.c%
947131Sbostic  */
1047131Sbostic 
1147131Sbostic #ifndef lint
1260698Sbostic static char copyright[] =
1360698Sbostic "@(#) Copyright (c) 1991, 1993\n\
1460698Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1547131Sbostic #endif /* not lint */
1647131Sbostic 
1747131Sbostic #ifndef lint
18*69272Schristos static char sccsid[] = "@(#)mknodes.c	8.2 (Berkeley) 05/04/95";
1947131Sbostic #endif /* not lint */
2047131Sbostic 
2147131Sbostic /*
2247131Sbostic  * This program reads the nodetypes file and nodes.c.pat file.  It generates
2347131Sbostic  * the files nodes.h and nodes.c.
2447131Sbostic  */
2547131Sbostic 
2647131Sbostic #include <stdio.h>
27*69272Schristos #include <stdlib.h>
28*69272Schristos #include <string.h>
29*69272Schristos #if __STDC__
30*69272Schristos #include <stdarg.h>
31*69272Schristos #else
32*69272Schristos #include <varargs.h>
33*69272Schristos #endif
3447131Sbostic 
3547131Sbostic 
3647131Sbostic #define MAXTYPES 50		/* max number of node types */
3747131Sbostic #define MAXFIELDS 20		/* max fields in a structure */
3847131Sbostic #define BUFLEN 100		/* size of character buffers */
3947131Sbostic 
4047131Sbostic /* field types */
4147131Sbostic #define T_NODE 1		/* union node *field */
4247131Sbostic #define T_NODELIST 2		/* struct nodelist *field */
4347131Sbostic #define T_STRING 3
4447131Sbostic #define T_INT 4			/* int field */
4547131Sbostic #define T_OTHER 5		/* other */
4647131Sbostic #define T_TEMP 6		/* don't copy this field */
4747131Sbostic 
4847131Sbostic 
4947131Sbostic struct field {			/* a structure field */
5047131Sbostic 	char *name;		/* name of field */
5147131Sbostic 	int type;			/* type of field */
5247131Sbostic 	char *decl;		/* declaration of field */
5347131Sbostic };
5447131Sbostic 
5547131Sbostic 
5647131Sbostic struct str {			/* struct representing a node structure */
5747131Sbostic 	char *tag;		/* structure tag */
5847131Sbostic 	int nfields;		/* number of fields in the structure */
5947131Sbostic 	struct field field[MAXFIELDS];	/* the fields of the structure */
6047131Sbostic 	int done;			/* set if fully parsed */
6147131Sbostic };
6247131Sbostic 
6347131Sbostic 
64*69272Schristos static int ntypes;			/* number of node types */
65*69272Schristos static char *nodename[MAXTYPES];	/* names of the nodes */
66*69272Schristos static struct str *nodestr[MAXTYPES];	/* type of structure used by the node */
67*69272Schristos static int nstr;			/* number of structures */
68*69272Schristos static struct str str[MAXTYPES];	/* the structures */
69*69272Schristos static struct str *curstr;		/* current structure */
70*69272Schristos static FILE *infp = stdin;
71*69272Schristos static char line[1024];
72*69272Schristos static int linno;
73*69272Schristos static char *linep;
7447131Sbostic 
75*69272Schristos static void parsenode __P((void));
76*69272Schristos static void parsefield __P((void));
77*69272Schristos static void output __P((char *));
78*69272Schristos static void outsizes __P((FILE *));
79*69272Schristos static void outfunc __P((FILE *, int));
80*69272Schristos static void indent __P((int, FILE *));
81*69272Schristos static int nextfield __P((char *));
82*69272Schristos static void skipbl __P((void));
83*69272Schristos static int readline __P((void));
84*69272Schristos static void error __P((const char *, ...));
85*69272Schristos static char *savestr __P((const char *));
8647131Sbostic 
8747131Sbostic 
88*69272Schristos int
main(argc,argv)8947131Sbostic main(argc, argv)
90*69272Schristos 	int argc;
9147131Sbostic 	char **argv;
92*69272Schristos {
9347131Sbostic 	if (argc != 3)
9447131Sbostic 		error("usage: mknodes file\n");
9547131Sbostic 	if ((infp = fopen(argv[1], "r")) == NULL)
9647131Sbostic 		error("Can't open %s", argv[1]);
9747131Sbostic 	while (readline()) {
9847131Sbostic 		if (line[0] == ' ' || line[0] == '\t')
9947131Sbostic 			parsefield();
10047131Sbostic 		else if (line[0] != '\0')
10147131Sbostic 			parsenode();
10247131Sbostic 	}
10347131Sbostic 	output(argv[2]);
10450620Storek 	exit(0);
10547131Sbostic }
10647131Sbostic 
10747131Sbostic 
10847131Sbostic 
109*69272Schristos static void
parsenode()110*69272Schristos parsenode()
111*69272Schristos {
11247131Sbostic 	char name[BUFLEN];
11347131Sbostic 	char tag[BUFLEN];
11447131Sbostic 	struct str *sp;
11547131Sbostic 
11647131Sbostic 	if (curstr && curstr->nfields > 0)
11747131Sbostic 		curstr->done = 1;
11847131Sbostic 	nextfield(name);
11947131Sbostic 	if (! nextfield(tag))
12047131Sbostic 		error("Tag expected");
12147131Sbostic 	if (*linep != '\0')
12247131Sbostic 		error("Garbage at end of line");
12347131Sbostic 	nodename[ntypes] = savestr(name);
12447131Sbostic 	for (sp = str ; sp < str + nstr ; sp++) {
125*69272Schristos 		if (strcmp(sp->tag, tag) == 0)
12647131Sbostic 			break;
12747131Sbostic 	}
12847131Sbostic 	if (sp >= str + nstr) {
12947131Sbostic 		sp->tag = savestr(tag);
13047131Sbostic 		sp->nfields = 0;
13147131Sbostic 		curstr = sp;
13247131Sbostic 		nstr++;
13347131Sbostic 	}
13447131Sbostic 	nodestr[ntypes] = sp;
13547131Sbostic 	ntypes++;
13647131Sbostic }
13747131Sbostic 
13847131Sbostic 
139*69272Schristos static void
parsefield()140*69272Schristos parsefield()
141*69272Schristos {
14247131Sbostic 	char name[BUFLEN];
14347131Sbostic 	char type[BUFLEN];
14447131Sbostic 	char decl[2 * BUFLEN];
14547131Sbostic 	struct field *fp;
14647131Sbostic 
14747131Sbostic 	if (curstr == NULL || curstr->done)
14847131Sbostic 		error("No current structure to add field to");
14947131Sbostic 	if (! nextfield(name))
15047131Sbostic 		error("No field name");
15147131Sbostic 	if (! nextfield(type))
15247131Sbostic 		error("No field type");
15347131Sbostic 	fp = &curstr->field[curstr->nfields];
15447131Sbostic 	fp->name = savestr(name);
155*69272Schristos 	if (strcmp(type, "nodeptr") == 0) {
15647131Sbostic 		fp->type = T_NODE;
15747131Sbostic 		sprintf(decl, "union node *%s", name);
158*69272Schristos 	} else if (strcmp(type, "nodelist") == 0) {
15947131Sbostic 		fp->type = T_NODELIST;
16047131Sbostic 		sprintf(decl, "struct nodelist *%s", name);
161*69272Schristos 	} else if (strcmp(type, "string") == 0) {
16247131Sbostic 		fp->type = T_STRING;
16347131Sbostic 		sprintf(decl, "char *%s", name);
164*69272Schristos 	} else if (strcmp(type, "int") == 0) {
16547131Sbostic 		fp->type = T_INT;
16647131Sbostic 		sprintf(decl, "int %s", name);
167*69272Schristos 	} else if (strcmp(type, "other") == 0) {
16847131Sbostic 		fp->type = T_OTHER;
169*69272Schristos 	} else if (strcmp(type, "temp") == 0) {
17047131Sbostic 		fp->type = T_TEMP;
17147131Sbostic 	} else {
17247131Sbostic 		error("Unknown type %s", type);
17347131Sbostic 	}
17447131Sbostic 	if (fp->type == T_OTHER || fp->type == T_TEMP) {
17547131Sbostic 		skipbl();
17647131Sbostic 		fp->decl = savestr(linep);
17747131Sbostic 	} else {
17847131Sbostic 		if (*linep)
17947131Sbostic 			error("Garbage at end of line");
18047131Sbostic 		fp->decl = savestr(decl);
18147131Sbostic 	}
18247131Sbostic 	curstr->nfields++;
18347131Sbostic }
18447131Sbostic 
18547131Sbostic 
18647131Sbostic char writer[] = "\
18747131Sbostic /*\n\
18847131Sbostic  * This file was generated by the mknodes program.\n\
18947131Sbostic  */\n\
19047131Sbostic \n";
19147131Sbostic 
192*69272Schristos static void
output(file)19347131Sbostic output(file)
19447131Sbostic 	char *file;
195*69272Schristos {
19647131Sbostic 	FILE *hfile;
19747131Sbostic 	FILE *cfile;
19847131Sbostic 	FILE *patfile;
19947131Sbostic 	int i;
20047131Sbostic 	struct str *sp;
20147131Sbostic 	struct field *fp;
20247131Sbostic 	char *p;
20347131Sbostic 
20447131Sbostic 	if ((patfile = fopen(file, "r")) == NULL)
20547131Sbostic 		error("Can't open %s", file);
20647131Sbostic 	if ((hfile = fopen("nodes.h", "w")) == NULL)
20747131Sbostic 		error("Can't create nodes.h");
20847131Sbostic 	if ((cfile = fopen("nodes.c", "w")) == NULL)
20947131Sbostic 		error("Can't create nodes.c");
21047131Sbostic 	fputs(writer, hfile);
21147131Sbostic 	for (i = 0 ; i < ntypes ; i++)
21247131Sbostic 		fprintf(hfile, "#define %s %d\n", nodename[i], i);
21347131Sbostic 	fputs("\n\n\n", hfile);
21447131Sbostic 	for (sp = str ; sp < &str[nstr] ; sp++) {
21547131Sbostic 		fprintf(hfile, "struct %s {\n", sp->tag);
21647131Sbostic 		for (i = sp->nfields, fp = sp->field ; --i >= 0 ; fp++) {
21747131Sbostic 			fprintf(hfile, "      %s;\n", fp->decl);
21847131Sbostic 		}
21947131Sbostic 		fputs("};\n\n\n", hfile);
22047131Sbostic 	}
22147131Sbostic 	fputs("union node {\n", hfile);
22247131Sbostic 	fprintf(hfile, "      int type;\n");
22347131Sbostic 	for (sp = str ; sp < &str[nstr] ; sp++) {
22447131Sbostic 		fprintf(hfile, "      struct %s %s;\n", sp->tag, sp->tag);
22547131Sbostic 	}
22647131Sbostic 	fputs("};\n\n\n", hfile);
22747131Sbostic 	fputs("struct nodelist {\n", hfile);
22847131Sbostic 	fputs("\tstruct nodelist *next;\n", hfile);
22947131Sbostic 	fputs("\tunion node *n;\n", hfile);
23047131Sbostic 	fputs("};\n\n\n", hfile);
23147131Sbostic 	fputs("#ifdef __STDC__\n", hfile);
23247131Sbostic 	fputs("union node *copyfunc(union node *);\n", hfile);
23347131Sbostic 	fputs("void freefunc(union node *);\n", hfile);
23447131Sbostic 	fputs("#else\n", hfile);
23547131Sbostic 	fputs("union node *copyfunc();\n", hfile);
23647131Sbostic 	fputs("void freefunc();\n", hfile);
23747131Sbostic 	fputs("#endif\n", hfile);
23847131Sbostic 
23947131Sbostic 	fputs(writer, cfile);
24047131Sbostic 	while (fgets(line, sizeof line, patfile) != NULL) {
24147131Sbostic 		for (p = line ; *p == ' ' || *p == '\t' ; p++);
242*69272Schristos 		if (strcmp(p, "%SIZES\n") == 0)
24347131Sbostic 			outsizes(cfile);
244*69272Schristos 		else if (strcmp(p, "%CALCSIZE\n") == 0)
24547131Sbostic 			outfunc(cfile, 1);
246*69272Schristos 		else if (strcmp(p, "%COPY\n") == 0)
24747131Sbostic 			outfunc(cfile, 0);
24847131Sbostic 		else
24947131Sbostic 			fputs(line, cfile);
25047131Sbostic 	}
25147131Sbostic }
25247131Sbostic 
25347131Sbostic 
25447131Sbostic 
255*69272Schristos static void
outsizes(cfile)25647131Sbostic outsizes(cfile)
25747131Sbostic 	FILE *cfile;
258*69272Schristos {
25947131Sbostic 	int i;
26047131Sbostic 
26147131Sbostic 	fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes);
26247131Sbostic 	for (i = 0 ; i < ntypes ; i++) {
26347131Sbostic 		fprintf(cfile, "      ALIGN(sizeof (struct %s)),\n", nodestr[i]->tag);
26447131Sbostic 	}
26547131Sbostic 	fprintf(cfile, "};\n");
26647131Sbostic }
26747131Sbostic 
26847131Sbostic 
269*69272Schristos static void
outfunc(cfile,calcsize)27047131Sbostic outfunc(cfile, calcsize)
27147131Sbostic 	FILE *cfile;
272*69272Schristos 	int calcsize;
273*69272Schristos {
27447131Sbostic 	struct str *sp;
27547131Sbostic 	struct field *fp;
27647131Sbostic 	int i;
27747131Sbostic 
27847131Sbostic 	fputs("      if (n == NULL)\n", cfile);
27947131Sbostic 	if (calcsize)
28047131Sbostic 		fputs("	    return;\n", cfile);
28147131Sbostic 	else
28247131Sbostic 		fputs("	    return NULL;\n", cfile);
28347131Sbostic 	if (calcsize)
28447131Sbostic 		fputs("      funcblocksize += nodesize[n->type];\n", cfile);
28547131Sbostic 	else {
28647131Sbostic 		fputs("      new = funcblock;\n", cfile);
28747131Sbostic 		fputs("      funcblock += nodesize[n->type];\n", cfile);
28847131Sbostic 	}
28947131Sbostic 	fputs("      switch (n->type) {\n", cfile);
29047131Sbostic 	for (sp = str ; sp < &str[nstr] ; sp++) {
29147131Sbostic 		for (i = 0 ; i < ntypes ; i++) {
29247131Sbostic 			if (nodestr[i] == sp)
29347131Sbostic 				fprintf(cfile, "      case %s:\n", nodename[i]);
29447131Sbostic 		}
29547131Sbostic 		for (i = sp->nfields ; --i >= 1 ; ) {
29647131Sbostic 			fp = &sp->field[i];
29747131Sbostic 			switch (fp->type) {
29847131Sbostic 			case T_NODE:
29947131Sbostic 				if (calcsize) {
30047131Sbostic 					indent(12, cfile);
30147131Sbostic 					fprintf(cfile, "calcsize(n->%s.%s);\n",
30247131Sbostic 						sp->tag, fp->name);
30347131Sbostic 				} else {
30447131Sbostic 					indent(12, cfile);
30547131Sbostic 					fprintf(cfile, "new->%s.%s = copynode(n->%s.%s);\n",
30647131Sbostic 						sp->tag, fp->name, sp->tag, fp->name);
30747131Sbostic 				}
30847131Sbostic 				break;
30947131Sbostic 			case T_NODELIST:
31047131Sbostic 				if (calcsize) {
31147131Sbostic 					indent(12, cfile);
31247131Sbostic 					fprintf(cfile, "sizenodelist(n->%s.%s);\n",
31347131Sbostic 						sp->tag, fp->name);
31447131Sbostic 				} else {
31547131Sbostic 					indent(12, cfile);
31647131Sbostic 					fprintf(cfile, "new->%s.%s = copynodelist(n->%s.%s);\n",
31747131Sbostic 						sp->tag, fp->name, sp->tag, fp->name);
31847131Sbostic 				}
31947131Sbostic 				break;
32047131Sbostic 			case T_STRING:
32147131Sbostic 				if (calcsize) {
32247131Sbostic 					indent(12, cfile);
32347131Sbostic 					fprintf(cfile, "funcstringsize += strlen(n->%s.%s) + 1;\n",
32447131Sbostic 						sp->tag, fp->name);
32547131Sbostic 				} else {
32647131Sbostic 					indent(12, cfile);
32747131Sbostic 					fprintf(cfile, "new->%s.%s = nodesavestr(n->%s.%s);\n",
32847131Sbostic 						sp->tag, fp->name, sp->tag, fp->name);
32947131Sbostic 				}
33047131Sbostic 				break;
33147131Sbostic 			case T_INT:
33247131Sbostic 			case T_OTHER:
33347131Sbostic 				if (! calcsize) {
33447131Sbostic 					indent(12, cfile);
33547131Sbostic 					fprintf(cfile, "new->%s.%s = n->%s.%s;\n",
33647131Sbostic 						sp->tag, fp->name, sp->tag, fp->name);
33747131Sbostic 				}
33847131Sbostic 				break;
33947131Sbostic 			}
34047131Sbostic 		}
34147131Sbostic 		indent(12, cfile);
34247131Sbostic 		fputs("break;\n", cfile);
34347131Sbostic 	}
34447131Sbostic 	fputs("      };\n", cfile);
34547131Sbostic 	if (! calcsize)
34647131Sbostic 		fputs("      new->type = n->type;\n", cfile);
34747131Sbostic }
34847131Sbostic 
34947131Sbostic 
350*69272Schristos static void
indent(amount,fp)35147131Sbostic indent(amount, fp)
352*69272Schristos 	int amount;
35347131Sbostic 	FILE *fp;
354*69272Schristos {
35547131Sbostic 	while (amount >= 8) {
35647131Sbostic 		putc('\t', fp);
35747131Sbostic 		amount -= 8;
35847131Sbostic 	}
35947131Sbostic 	while (--amount >= 0) {
36047131Sbostic 		putc(' ', fp);
36147131Sbostic 	}
36247131Sbostic }
36347131Sbostic 
36447131Sbostic 
365*69272Schristos static int
nextfield(buf)36647131Sbostic nextfield(buf)
36747131Sbostic 	char *buf;
368*69272Schristos {
36947131Sbostic 	register char *p, *q;
37047131Sbostic 
37147131Sbostic 	p = linep;
37247131Sbostic 	while (*p == ' ' || *p == '\t')
37347131Sbostic 		p++;
37447131Sbostic 	q = buf;
37547131Sbostic 	while (*p != ' ' && *p != '\t' && *p != '\0')
37647131Sbostic 		*q++ = *p++;
37747131Sbostic 	*q = '\0';
37847131Sbostic 	linep = p;
37947131Sbostic 	return (q > buf);
38047131Sbostic }
38147131Sbostic 
38247131Sbostic 
383*69272Schristos static void
skipbl()384*69272Schristos skipbl()
385*69272Schristos {
38647131Sbostic 	while (*linep == ' ' || *linep == '\t')
38747131Sbostic 		linep++;
38847131Sbostic }
38947131Sbostic 
39047131Sbostic 
391*69272Schristos static int
readline()392*69272Schristos readline()
393*69272Schristos {
39447131Sbostic 	register char *p;
39547131Sbostic 
39647131Sbostic 	if (fgets(line, 1024, infp) == NULL)
39747131Sbostic 		return 0;
39847131Sbostic 	for (p = line ; *p != '#' && *p != '\n' && *p != '\0' ; p++);
39947131Sbostic 	while (p > line && (p[-1] == ' ' || p[-1] == '\t'))
40047131Sbostic 		p--;
40147131Sbostic 	*p = '\0';
40247131Sbostic 	linep = line;
40347131Sbostic 	linno++;
40447131Sbostic 	if (p - line > BUFLEN)
40547131Sbostic 		error("Line too long");
40647131Sbostic 	return 1;
40747131Sbostic }
40847131Sbostic 
40947131Sbostic 
41047131Sbostic 
411*69272Schristos static void
412*69272Schristos #if __STDC__
error(const char * msg,...)413*69272Schristos error(const char *msg, ...)
414*69272Schristos #else
415*69272Schristos error(va_alist)
416*69272Schristos 	va_dcl
417*69272Schristos #endif
418*69272Schristos {
419*69272Schristos 	va_list va;
420*69272Schristos #if __STDC__
421*69272Schristos 	va_start(va, msg);
422*69272Schristos #else
42347131Sbostic 	char *msg;
424*69272Schristos 	va_start(va);
425*69272Schristos 	msg = va_arg(va, char *);
426*69272Schristos #endif
427*69272Schristos 
428*69272Schristos 	(void) fprintf(stderr, "line %d: ", linno);
429*69272Schristos 	(void) vfprintf(stderr, msg, va);
430*69272Schristos 	(void) fputc('\n', stderr);
431*69272Schristos 
432*69272Schristos 	va_end(va);
433*69272Schristos 
43447131Sbostic 	exit(2);
43547131Sbostic }
43647131Sbostic 
43747131Sbostic 
43847131Sbostic 
439*69272Schristos static char *
savestr(s)44047131Sbostic savestr(s)
441*69272Schristos 	const char *s;
442*69272Schristos {
44347131Sbostic 	register char *p;
44447131Sbostic 
44547131Sbostic 	if ((p = malloc(strlen(s) + 1)) == NULL)
44647131Sbostic 		error("Out of space");
447*69272Schristos 	(void) strcpy(p, s);
44847131Sbostic 	return p;
44947131Sbostic }
450