mknodes.c revision 99110
11556Srgrimes/*- 21556Srgrimes * Copyright (c) 1991, 1993 31556Srgrimes * The Regents of the University of California. All rights reserved. 41556Srgrimes * 51556Srgrimes * This code is derived from software contributed to Berkeley by 61556Srgrimes * Kenneth Almquist. 71556Srgrimes * 81556Srgrimes * Redistribution and use in source and binary forms, with or without 91556Srgrimes * modification, are permitted provided that the following conditions 101556Srgrimes * are met: 111556Srgrimes * 1. Redistributions of source code must retain the above copyright 121556Srgrimes * notice, this list of conditions and the following disclaimer. 131556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141556Srgrimes * notice, this list of conditions and the following disclaimer in the 151556Srgrimes * documentation and/or other materials provided with the distribution. 161556Srgrimes * 3. All advertising materials mentioning features or use of this software 171556Srgrimes * must display the following acknowledgement: 181556Srgrimes * This product includes software developed by the University of 191556Srgrimes * California, Berkeley and its contributors. 201556Srgrimes * 4. Neither the name of the University nor the names of its contributors 211556Srgrimes * may be used to endorse or promote products derived from this software 221556Srgrimes * without specific prior written permission. 231556Srgrimes * 241556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341556Srgrimes * SUCH DAMAGE. 351556Srgrimes */ 361556Srgrimes 371556Srgrimes#ifndef lint 3820425Sstevestatic char const copyright[] = 391556Srgrimes"@(#) Copyright (c) 1991, 1993\n\ 401556Srgrimes The Regents of the University of California. All rights reserved.\n"; 411556Srgrimes#endif /* not lint */ 421556Srgrimes 431556Srgrimes#ifndef lint 4436150Scharnier#if 0 4536150Scharnierstatic char sccsid[] = "@(#)mknodes.c 8.2 (Berkeley) 5/4/95"; 4636150Scharnier#endif 471556Srgrimes#endif /* not lint */ 4899110Sobrien#include <sys/cdefs.h> 4999110Sobrien__FBSDID("$FreeBSD: head/bin/sh/mknodes.c 99110 2002-06-30 05:15:05Z obrien $"); 501556Srgrimes 511556Srgrimes/* 521556Srgrimes * This program reads the nodetypes file and nodes.c.pat file. It generates 531556Srgrimes * the files nodes.h and nodes.c. 541556Srgrimes */ 551556Srgrimes 561556Srgrimes#include <stdio.h> 5717987Speter#include <stdlib.h> 5817987Speter#include <string.h> 5953891Scracauer#include <errno.h> 6017987Speter#include <stdarg.h> 611556Srgrimes 621556Srgrimes#define MAXTYPES 50 /* max number of node types */ 631556Srgrimes#define MAXFIELDS 20 /* max fields in a structure */ 641556Srgrimes#define BUFLEN 100 /* size of character buffers */ 651556Srgrimes 661556Srgrimes/* field types */ 671556Srgrimes#define T_NODE 1 /* union node *field */ 681556Srgrimes#define T_NODELIST 2 /* struct nodelist *field */ 691556Srgrimes#define T_STRING 3 701556Srgrimes#define T_INT 4 /* int field */ 711556Srgrimes#define T_OTHER 5 /* other */ 721556Srgrimes#define T_TEMP 6 /* don't copy this field */ 731556Srgrimes 741556Srgrimes 751556Srgrimesstruct field { /* a structure field */ 761556Srgrimes char *name; /* name of field */ 771556Srgrimes int type; /* type of field */ 781556Srgrimes char *decl; /* declaration of field */ 791556Srgrimes}; 801556Srgrimes 811556Srgrimes 821556Srgrimesstruct str { /* struct representing a node structure */ 831556Srgrimes char *tag; /* structure tag */ 841556Srgrimes int nfields; /* number of fields in the structure */ 851556Srgrimes struct field field[MAXFIELDS]; /* the fields of the structure */ 861556Srgrimes int done; /* set if fully parsed */ 871556Srgrimes}; 881556Srgrimes 891556Srgrimes 9017987Speterstatic int ntypes; /* number of node types */ 9117987Speterstatic char *nodename[MAXTYPES]; /* names of the nodes */ 9217987Speterstatic struct str *nodestr[MAXTYPES]; /* type of structure used by the node */ 9317987Speterstatic int nstr; /* number of structures */ 9417987Speterstatic struct str str[MAXTYPES]; /* the structures */ 9517987Speterstatic struct str *curstr; /* current structure */ 9681602Speterstatic FILE *infp; 9717987Speterstatic char line[1024]; 9817987Speterstatic int linno; 9917987Speterstatic char *linep; 1001556Srgrimes 10190111Simpstatic void parsenode(void); 10290111Simpstatic void parsefield(void); 10390111Simpstatic void output(char *); 10490111Simpstatic void outsizes(FILE *); 10590111Simpstatic void outfunc(FILE *, int); 10690111Simpstatic void indent(int, FILE *); 10790111Simpstatic int nextfield(char *); 10890111Simpstatic void skipbl(void); 10990111Simpstatic int readline(void); 11090111Simpstatic void error(const char *, ...) __printf0like(1, 2); 11190111Simpstatic char *savestr(const char *); 1121556Srgrimes 1131556Srgrimes 11417987Speterint 11590111Simpmain(int argc, char *argv[]) 11617987Speter{ 1171556Srgrimes if (argc != 3) 11818016Speter error("usage: mknodes file"); 11981602Speter infp = stdin; 1201556Srgrimes if ((infp = fopen(argv[1], "r")) == NULL) 12153891Scracauer error("Can't open %s: %s", argv[1], strerror(errno)); 1221556Srgrimes while (readline()) { 1231556Srgrimes if (line[0] == ' ' || line[0] == '\t') 1241556Srgrimes parsefield(); 1251556Srgrimes else if (line[0] != '\0') 1261556Srgrimes parsenode(); 1271556Srgrimes } 1281556Srgrimes output(argv[2]); 1291556Srgrimes exit(0); 1301556Srgrimes} 1311556Srgrimes 1321556Srgrimes 1331556Srgrimes 13417987Speterstatic void 13590111Simpparsenode(void) 13617987Speter{ 1371556Srgrimes char name[BUFLEN]; 1381556Srgrimes char tag[BUFLEN]; 1391556Srgrimes struct str *sp; 1401556Srgrimes 1411556Srgrimes if (curstr && curstr->nfields > 0) 1421556Srgrimes curstr->done = 1; 1431556Srgrimes nextfield(name); 1441556Srgrimes if (! nextfield(tag)) 1451556Srgrimes error("Tag expected"); 1461556Srgrimes if (*linep != '\0') 1471556Srgrimes error("Garbage at end of line"); 1481556Srgrimes nodename[ntypes] = savestr(name); 1491556Srgrimes for (sp = str ; sp < str + nstr ; sp++) { 15017987Speter if (strcmp(sp->tag, tag) == 0) 1511556Srgrimes break; 1521556Srgrimes } 1531556Srgrimes if (sp >= str + nstr) { 1541556Srgrimes sp->tag = savestr(tag); 1551556Srgrimes sp->nfields = 0; 1561556Srgrimes curstr = sp; 1571556Srgrimes nstr++; 1581556Srgrimes } 1591556Srgrimes nodestr[ntypes] = sp; 1601556Srgrimes ntypes++; 1611556Srgrimes} 1621556Srgrimes 1631556Srgrimes 16417987Speterstatic void 16590111Simpparsefield(void) 16617987Speter{ 1671556Srgrimes char name[BUFLEN]; 1681556Srgrimes char type[BUFLEN]; 1691556Srgrimes char decl[2 * BUFLEN]; 1701556Srgrimes struct field *fp; 1711556Srgrimes 1721556Srgrimes if (curstr == NULL || curstr->done) 1731556Srgrimes error("No current structure to add field to"); 1741556Srgrimes if (! nextfield(name)) 1751556Srgrimes error("No field name"); 1761556Srgrimes if (! nextfield(type)) 1771556Srgrimes error("No field type"); 1781556Srgrimes fp = &curstr->field[curstr->nfields]; 1791556Srgrimes fp->name = savestr(name); 18017987Speter if (strcmp(type, "nodeptr") == 0) { 1811556Srgrimes fp->type = T_NODE; 1821556Srgrimes sprintf(decl, "union node *%s", name); 18317987Speter } else if (strcmp(type, "nodelist") == 0) { 1841556Srgrimes fp->type = T_NODELIST; 1851556Srgrimes sprintf(decl, "struct nodelist *%s", name); 18617987Speter } else if (strcmp(type, "string") == 0) { 1871556Srgrimes fp->type = T_STRING; 1881556Srgrimes sprintf(decl, "char *%s", name); 18917987Speter } else if (strcmp(type, "int") == 0) { 1901556Srgrimes fp->type = T_INT; 1911556Srgrimes sprintf(decl, "int %s", name); 19217987Speter } else if (strcmp(type, "other") == 0) { 1931556Srgrimes fp->type = T_OTHER; 19417987Speter } else if (strcmp(type, "temp") == 0) { 1951556Srgrimes fp->type = T_TEMP; 1961556Srgrimes } else { 1971556Srgrimes error("Unknown type %s", type); 1981556Srgrimes } 1991556Srgrimes if (fp->type == T_OTHER || fp->type == T_TEMP) { 2001556Srgrimes skipbl(); 2011556Srgrimes fp->decl = savestr(linep); 2021556Srgrimes } else { 2031556Srgrimes if (*linep) 2041556Srgrimes error("Garbage at end of line"); 2051556Srgrimes fp->decl = savestr(decl); 2061556Srgrimes } 2071556Srgrimes curstr->nfields++; 2081556Srgrimes} 2091556Srgrimes 2101556Srgrimes 2111556Srgrimeschar writer[] = "\ 2121556Srgrimes/*\n\ 2131556Srgrimes * This file was generated by the mknodes program.\n\ 2141556Srgrimes */\n\ 2151556Srgrimes\n"; 2161556Srgrimes 21717987Speterstatic void 21890111Simpoutput(char *file) 21917987Speter{ 2201556Srgrimes FILE *hfile; 2211556Srgrimes FILE *cfile; 2221556Srgrimes FILE *patfile; 2231556Srgrimes int i; 2241556Srgrimes struct str *sp; 2251556Srgrimes struct field *fp; 2261556Srgrimes char *p; 2271556Srgrimes 2281556Srgrimes if ((patfile = fopen(file, "r")) == NULL) 22953891Scracauer error("Can't open %s: %s", file, strerror(errno)); 2301556Srgrimes if ((hfile = fopen("nodes.h", "w")) == NULL) 23153891Scracauer error("Can't create nodes.h: %s", strerror(errno)); 2321556Srgrimes if ((cfile = fopen("nodes.c", "w")) == NULL) 2331556Srgrimes error("Can't create nodes.c"); 2341556Srgrimes fputs(writer, hfile); 2351556Srgrimes for (i = 0 ; i < ntypes ; i++) 2361556Srgrimes fprintf(hfile, "#define %s %d\n", nodename[i], i); 2371556Srgrimes fputs("\n\n\n", hfile); 2381556Srgrimes for (sp = str ; sp < &str[nstr] ; sp++) { 2391556Srgrimes fprintf(hfile, "struct %s {\n", sp->tag); 2401556Srgrimes for (i = sp->nfields, fp = sp->field ; --i >= 0 ; fp++) { 2411556Srgrimes fprintf(hfile, " %s;\n", fp->decl); 2421556Srgrimes } 2431556Srgrimes fputs("};\n\n\n", hfile); 2441556Srgrimes } 2451556Srgrimes fputs("union node {\n", hfile); 2461556Srgrimes fprintf(hfile, " int type;\n"); 2471556Srgrimes for (sp = str ; sp < &str[nstr] ; sp++) { 2481556Srgrimes fprintf(hfile, " struct %s %s;\n", sp->tag, sp->tag); 2491556Srgrimes } 2501556Srgrimes fputs("};\n\n\n", hfile); 2511556Srgrimes fputs("struct nodelist {\n", hfile); 2521556Srgrimes fputs("\tstruct nodelist *next;\n", hfile); 2531556Srgrimes fputs("\tunion node *n;\n", hfile); 2541556Srgrimes fputs("};\n\n\n", hfile); 2551556Srgrimes fputs("union node *copyfunc(union node *);\n", hfile); 2561556Srgrimes fputs("void freefunc(union node *);\n", hfile); 2571556Srgrimes 2581556Srgrimes fputs(writer, cfile); 2591556Srgrimes while (fgets(line, sizeof line, patfile) != NULL) { 2601556Srgrimes for (p = line ; *p == ' ' || *p == '\t' ; p++); 26117987Speter if (strcmp(p, "%SIZES\n") == 0) 2621556Srgrimes outsizes(cfile); 26317987Speter else if (strcmp(p, "%CALCSIZE\n") == 0) 2641556Srgrimes outfunc(cfile, 1); 26517987Speter else if (strcmp(p, "%COPY\n") == 0) 2661556Srgrimes outfunc(cfile, 0); 2671556Srgrimes else 2681556Srgrimes fputs(line, cfile); 2691556Srgrimes } 2701556Srgrimes} 2711556Srgrimes 2721556Srgrimes 2731556Srgrimes 27417987Speterstatic void 27590111Simpoutsizes(FILE *cfile) 27617987Speter{ 2771556Srgrimes int i; 2781556Srgrimes 2791556Srgrimes fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes); 2801556Srgrimes for (i = 0 ; i < ntypes ; i++) { 2811556Srgrimes fprintf(cfile, " ALIGN(sizeof (struct %s)),\n", nodestr[i]->tag); 2821556Srgrimes } 2831556Srgrimes fprintf(cfile, "};\n"); 2841556Srgrimes} 2851556Srgrimes 2861556Srgrimes 28717987Speterstatic void 28890111Simpoutfunc(FILE *cfile, int calcsize) 28917987Speter{ 2901556Srgrimes struct str *sp; 2911556Srgrimes struct field *fp; 2921556Srgrimes int i; 2931556Srgrimes 2941556Srgrimes fputs(" if (n == NULL)\n", cfile); 2951556Srgrimes if (calcsize) 2961556Srgrimes fputs(" return;\n", cfile); 2971556Srgrimes else 2981556Srgrimes fputs(" return NULL;\n", cfile); 2991556Srgrimes if (calcsize) 3001556Srgrimes fputs(" funcblocksize += nodesize[n->type];\n", cfile); 3011556Srgrimes else { 3021556Srgrimes fputs(" new = funcblock;\n", cfile); 30325226Ssteve fputs(" funcblock = (char *)funcblock + nodesize[n->type];\n", cfile); 3041556Srgrimes } 3051556Srgrimes fputs(" switch (n->type) {\n", cfile); 3061556Srgrimes for (sp = str ; sp < &str[nstr] ; sp++) { 3071556Srgrimes for (i = 0 ; i < ntypes ; i++) { 3081556Srgrimes if (nodestr[i] == sp) 3091556Srgrimes fprintf(cfile, " case %s:\n", nodename[i]); 3101556Srgrimes } 3111556Srgrimes for (i = sp->nfields ; --i >= 1 ; ) { 3121556Srgrimes fp = &sp->field[i]; 3131556Srgrimes switch (fp->type) { 3141556Srgrimes case T_NODE: 3151556Srgrimes if (calcsize) { 3161556Srgrimes indent(12, cfile); 3171556Srgrimes fprintf(cfile, "calcsize(n->%s.%s);\n", 3181556Srgrimes sp->tag, fp->name); 3191556Srgrimes } else { 3201556Srgrimes indent(12, cfile); 3211556Srgrimes fprintf(cfile, "new->%s.%s = copynode(n->%s.%s);\n", 3221556Srgrimes sp->tag, fp->name, sp->tag, fp->name); 3231556Srgrimes } 3241556Srgrimes break; 3251556Srgrimes case T_NODELIST: 3261556Srgrimes if (calcsize) { 3271556Srgrimes indent(12, cfile); 3281556Srgrimes fprintf(cfile, "sizenodelist(n->%s.%s);\n", 3291556Srgrimes sp->tag, fp->name); 3301556Srgrimes } else { 3311556Srgrimes indent(12, cfile); 3321556Srgrimes fprintf(cfile, "new->%s.%s = copynodelist(n->%s.%s);\n", 3331556Srgrimes sp->tag, fp->name, sp->tag, fp->name); 3341556Srgrimes } 3351556Srgrimes break; 3361556Srgrimes case T_STRING: 3371556Srgrimes if (calcsize) { 3381556Srgrimes indent(12, cfile); 3391556Srgrimes fprintf(cfile, "funcstringsize += strlen(n->%s.%s) + 1;\n", 3401556Srgrimes sp->tag, fp->name); 3411556Srgrimes } else { 3421556Srgrimes indent(12, cfile); 3431556Srgrimes fprintf(cfile, "new->%s.%s = nodesavestr(n->%s.%s);\n", 3441556Srgrimes sp->tag, fp->name, sp->tag, fp->name); 3451556Srgrimes } 3461556Srgrimes break; 3471556Srgrimes case T_INT: 3481556Srgrimes case T_OTHER: 3491556Srgrimes if (! calcsize) { 3501556Srgrimes indent(12, cfile); 3511556Srgrimes fprintf(cfile, "new->%s.%s = n->%s.%s;\n", 3521556Srgrimes sp->tag, fp->name, sp->tag, fp->name); 3531556Srgrimes } 3541556Srgrimes break; 3551556Srgrimes } 3561556Srgrimes } 3571556Srgrimes indent(12, cfile); 3581556Srgrimes fputs("break;\n", cfile); 3591556Srgrimes } 3601556Srgrimes fputs(" };\n", cfile); 3611556Srgrimes if (! calcsize) 3621556Srgrimes fputs(" new->type = n->type;\n", cfile); 3631556Srgrimes} 3641556Srgrimes 3651556Srgrimes 36617987Speterstatic void 36790111Simpindent(int amount, FILE *fp) 36817987Speter{ 3691556Srgrimes while (amount >= 8) { 3701556Srgrimes putc('\t', fp); 3711556Srgrimes amount -= 8; 3721556Srgrimes } 3731556Srgrimes while (--amount >= 0) { 3741556Srgrimes putc(' ', fp); 3751556Srgrimes } 3761556Srgrimes} 3771556Srgrimes 3781556Srgrimes 37917987Speterstatic int 38090111Simpnextfield(char *buf) 38117987Speter{ 38225226Ssteve char *p, *q; 3831556Srgrimes 3841556Srgrimes p = linep; 3851556Srgrimes while (*p == ' ' || *p == '\t') 3861556Srgrimes p++; 3871556Srgrimes q = buf; 3881556Srgrimes while (*p != ' ' && *p != '\t' && *p != '\0') 3891556Srgrimes *q++ = *p++; 3901556Srgrimes *q = '\0'; 3911556Srgrimes linep = p; 3921556Srgrimes return (q > buf); 3931556Srgrimes} 3941556Srgrimes 3951556Srgrimes 39617987Speterstatic void 39790111Simpskipbl(void) 39817987Speter{ 3991556Srgrimes while (*linep == ' ' || *linep == '\t') 4001556Srgrimes linep++; 4011556Srgrimes} 4021556Srgrimes 4031556Srgrimes 40417987Speterstatic int 40590111Simpreadline(void) 40617987Speter{ 40725226Ssteve char *p; 4081556Srgrimes 4091556Srgrimes if (fgets(line, 1024, infp) == NULL) 4101556Srgrimes return 0; 4111556Srgrimes for (p = line ; *p != '#' && *p != '\n' && *p != '\0' ; p++); 4121556Srgrimes while (p > line && (p[-1] == ' ' || p[-1] == '\t')) 4131556Srgrimes p--; 4141556Srgrimes *p = '\0'; 4151556Srgrimes linep = line; 4161556Srgrimes linno++; 4171556Srgrimes if (p - line > BUFLEN) 4181556Srgrimes error("Line too long"); 4191556Srgrimes return 1; 4201556Srgrimes} 4211556Srgrimes 4221556Srgrimes 4231556Srgrimes 42417987Speterstatic void 42517987Spetererror(const char *msg, ...) 42617987Speter{ 42717987Speter va_list va; 42817987Speter va_start(va, msg); 42917987Speter 43017987Speter (void) fprintf(stderr, "line %d: ", linno); 43117987Speter (void) vfprintf(stderr, msg, va); 43217987Speter (void) fputc('\n', stderr); 43317987Speter 43417987Speter va_end(va); 43517987Speter 4361556Srgrimes exit(2); 4371556Srgrimes} 4381556Srgrimes 4391556Srgrimes 4401556Srgrimes 44117987Speterstatic char * 44290111Simpsavestr(const char *s) 44317987Speter{ 44425226Ssteve char *p; 4451556Srgrimes 4461556Srgrimes if ((p = malloc(strlen(s) + 1)) == NULL) 4471556Srgrimes error("Out of space"); 44817987Speter (void) strcpy(p, s); 4491556Srgrimes return p; 4501556Srgrimes} 451