00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef lint
00038 char copyright[] =
00039 "@(#) Copyright (c) 1991 The Regents of the University of California.\n\
00040 All rights reserved.\n";
00041 #endif
00042
00043 #ifndef lint
00044 static char sccsid[] = "@(#)mknodes.c 5.1 (Berkeley) 3/7/91";
00045 #endif
00046
00047
00048
00049
00050
00051
00052 #include <stdio.h>
00053
00054
00055 #define MAXTYPES 50
00056 #define MAXFIELDS 20
00057 #define BUFLEN 100
00058
00059
00060 #define T_NODE 1
00061 #define T_NODELIST 2
00062 #define T_STRING 3
00063 #define T_INT 4
00064 #define T_OTHER 5
00065 #define T_TEMP 6
00066
00067
00068 struct field {
00069 char *name;
00070 int type;
00071 char *decl;
00072 };
00073
00074
00075 struct str {
00076 char *tag;
00077 int nfields;
00078 struct field field[MAXFIELDS];
00079 int done;
00080 };
00081
00082
00083 int ntypes;
00084 char *nodename[MAXTYPES];
00085 struct str *nodestr[MAXTYPES];
00086 int nstr;
00087 struct str str[MAXTYPES];
00088 struct str *curstr;
00089
00090
00091 FILE *infp = stdin;
00092 char line[1024];
00093 int linno;
00094 char *linep;
00095
00096
00097 char *savestr();
00098 #define equal(s1, s2) (strcmp(s1, s2) == 0)
00099
00100
00101 main(argc, argv)
00102 char **argv;
00103 {
00104 if (argc != 3)
00105 error("usage: mknodes file\n");
00106 if ((infp = fopen(argv[1], "r")) == NULL)
00107 error("Can't open %s", argv[1]);
00108 while (readline()) {
00109 if (line[0] == ' ' || line[0] == '\t')
00110 parsefield();
00111 else if (line[0] != '\0')
00112 parsenode();
00113 }
00114 output(argv[2]);
00115 return 0;
00116 }
00117
00118
00119
00120 parsenode() {
00121 char name[BUFLEN];
00122 char tag[BUFLEN];
00123 struct str *sp;
00124
00125 if (curstr && curstr->nfields > 0)
00126 curstr->done = 1;
00127 nextfield(name);
00128 if (! nextfield(tag))
00129 error("Tag expected");
00130 if (*linep != '\0')
00131 error("Garbage at end of line");
00132 nodename[ntypes] = savestr(name);
00133 for (sp = str ; sp < str + nstr ; sp++) {
00134 if (equal(sp->tag, tag))
00135 break;
00136 }
00137 if (sp >= str + nstr) {
00138 sp->tag = savestr(tag);
00139 sp->nfields = 0;
00140 curstr = sp;
00141 nstr++;
00142 }
00143 nodestr[ntypes] = sp;
00144 ntypes++;
00145 }
00146
00147
00148 parsefield() {
00149 char name[BUFLEN];
00150 char type[BUFLEN];
00151 char decl[2 * BUFLEN];
00152 struct field *fp;
00153
00154 if (curstr == NULL || curstr->done)
00155 error("No current structure to add field to");
00156 if (! nextfield(name))
00157 error("No field name");
00158 if (! nextfield(type))
00159 error("No field type");
00160 fp = &curstr->field[curstr->nfields];
00161 fp->name = savestr(name);
00162 if (equal(type, "nodeptr")) {
00163 fp->type = T_NODE;
00164 sprintf(decl, "union node *%s", name);
00165 } else if (equal(type, "nodelist")) {
00166 fp->type = T_NODELIST;
00167 sprintf(decl, "struct nodelist *%s", name);
00168 } else if (equal(type, "string")) {
00169 fp->type = T_STRING;
00170 sprintf(decl, "char *%s", name);
00171 } else if (equal(type, "int")) {
00172 fp->type = T_INT;
00173 sprintf(decl, "int %s", name);
00174 } else if (equal(type, "other")) {
00175 fp->type = T_OTHER;
00176 } else if (equal(type, "temp")) {
00177 fp->type = T_TEMP;
00178 } else {
00179 error("Unknown type %s", type);
00180 }
00181 if (fp->type == T_OTHER || fp->type == T_TEMP) {
00182 skipbl();
00183 fp->decl = savestr(linep);
00184 } else {
00185 if (*linep)
00186 error("Garbage at end of line");
00187 fp->decl = savestr(decl);
00188 }
00189 curstr->nfields++;
00190 }
00191
00192
00193 char writer[] = "\
00194 /*\n\
00195 * This file was generated by the mknodes program.\n\
00196 */\n\
00197 \n";
00198
00199 output(file)
00200 char *file;
00201 {
00202 FILE *hfile;
00203 FILE *cfile;
00204 FILE *patfile;
00205 int i;
00206 struct str *sp;
00207 struct field *fp;
00208 char *p;
00209
00210 if ((patfile = fopen(file, "r")) == NULL)
00211 error("Can't open %s", file);
00212 if ((hfile = fopen("nodes.h", "w")) == NULL)
00213 error("Can't create nodes.h");
00214 if ((cfile = fopen("nodes.c", "w")) == NULL)
00215 error("Can't create nodes.c");
00216 fputs(writer, hfile);
00217 for (i = 0 ; i < ntypes ; i++)
00218 fprintf(hfile, "#define %s %d\n", nodename[i], i);
00219 fputs("\n\n\n", hfile);
00220 for (sp = str ; sp < &str[nstr] ; sp++) {
00221 fprintf(hfile, "struct %s {\n", sp->tag);
00222 for (i = sp->nfields, fp = sp->field ; --i >= 0 ; fp++) {
00223 fprintf(hfile, " %s;\n", fp->decl);
00224 }
00225 fputs("};\n\n\n", hfile);
00226 }
00227 fputs("union node {\n", hfile);
00228 fprintf(hfile, " int type;\n");
00229 for (sp = str ; sp < &str[nstr] ; sp++) {
00230 fprintf(hfile, " struct %s %s;\n", sp->tag, sp->tag);
00231 }
00232 fputs("};\n\n\n", hfile);
00233 fputs("struct nodelist {\n", hfile);
00234 fputs("\tstruct nodelist *next;\n", hfile);
00235 fputs("\tunion node *n;\n", hfile);
00236 fputs("};\n\n\n", hfile);
00237 fputs("#ifdef __STDC__\n", hfile);
00238 fputs("union node *copyfunc(union node *);\n", hfile);
00239 fputs("void freefunc(union node *);\n", hfile);
00240 fputs("#else\n", hfile);
00241 fputs("union node *copyfunc();\n", hfile);
00242 fputs("void freefunc();\n", hfile);
00243 fputs("#endif\n", hfile);
00244
00245 fputs(writer, cfile);
00246 while (fgets(line, sizeof line, patfile) != NULL) {
00247 for (p = line ; *p == ' ' || *p == '\t' ; p++);
00248 if (equal(p, "%SIZES\n"))
00249 outsizes(cfile);
00250 else if (equal(p, "%CALCSIZE\n"))
00251 outfunc(cfile, 1);
00252 else if (equal(p, "%COPY\n"))
00253 outfunc(cfile, 0);
00254 else
00255 fputs(line, cfile);
00256 }
00257 }
00258
00259
00260
00261 outsizes(cfile)
00262 FILE *cfile;
00263 {
00264 int i;
00265
00266 fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes);
00267 for (i = 0 ; i < ntypes ; i++) {
00268 fprintf(cfile, " ALIGN(sizeof (struct %s)),\n", nodestr[i]->tag);
00269 }
00270 fprintf(cfile, "};\n");
00271 }
00272
00273
00274 outfunc(cfile, calcsize)
00275 FILE *cfile;
00276 {
00277 struct str *sp;
00278 struct field *fp;
00279 int i;
00280
00281 fputs(" if (n == NULL)\n", cfile);
00282 if (calcsize)
00283 fputs(" return;\n", cfile);
00284 else
00285 fputs(" return NULL;\n", cfile);
00286 if (calcsize)
00287 fputs(" funcblocksize += nodesize[n->type];\n", cfile);
00288 else {
00289 fputs(" new = funcblock;\n", cfile);
00290 fputs(" *(char **)&funcblock += nodesize[n->type];\n",
00291 cfile);
00292 }
00293 fputs(" switch (n->type) {\n", cfile);
00294 for (sp = str ; sp < &str[nstr] ; sp++) {
00295 for (i = 0 ; i < ntypes ; i++) {
00296 if (nodestr[i] == sp)
00297 fprintf(cfile, " case %s:\n", nodename[i]);
00298 }
00299 for (i = sp->nfields ; --i >= 1 ; ) {
00300 fp = &sp->field[i];
00301 switch (fp->type) {
00302 case T_NODE:
00303 if (calcsize) {
00304 indent(12, cfile);
00305 fprintf(cfile, "calcsize(n->%s.%s);\n",
00306 sp->tag, fp->name);
00307 } else {
00308 indent(12, cfile);
00309 fprintf(cfile, "new->%s.%s = copynode(n->%s.%s);\n",
00310 sp->tag, fp->name, sp->tag, fp->name);
00311 }
00312 break;
00313 case T_NODELIST:
00314 if (calcsize) {
00315 indent(12, cfile);
00316 fprintf(cfile, "sizenodelist(n->%s.%s);\n",
00317 sp->tag, fp->name);
00318 } else {
00319 indent(12, cfile);
00320 fprintf(cfile, "new->%s.%s = copynodelist(n->%s.%s);\n",
00321 sp->tag, fp->name, sp->tag, fp->name);
00322 }
00323 break;
00324 case T_STRING:
00325 if (calcsize) {
00326 indent(12, cfile);
00327 fprintf(cfile, "funcstringsize += strlen(n->%s.%s) + 1;\n",
00328 sp->tag, fp->name);
00329 } else {
00330 indent(12, cfile);
00331 fprintf(cfile, "new->%s.%s = nodesavestr(n->%s.%s);\n",
00332 sp->tag, fp->name, sp->tag, fp->name);
00333 }
00334 break;
00335 case T_INT:
00336 case T_OTHER:
00337 if (! calcsize) {
00338 indent(12, cfile);
00339 fprintf(cfile, "new->%s.%s = n->%s.%s;\n",
00340 sp->tag, fp->name, sp->tag, fp->name);
00341 }
00342 break;
00343 }
00344 }
00345 indent(12, cfile);
00346 fputs("break;\n", cfile);
00347 }
00348 fputs(" };\n", cfile);
00349 if (! calcsize)
00350 fputs(" new->type = n->type;\n", cfile);
00351 }
00352
00353
00354 indent(amount, fp)
00355 FILE *fp;
00356 {
00357 while (amount >= 8) {
00358 putc('\t', fp);
00359 amount -= 8;
00360 }
00361 while (--amount >= 0) {
00362 putc(' ', fp);
00363 }
00364 }
00365
00366
00367 int
00368 nextfield(buf)
00369 char *buf;
00370 {
00371 register char *p, *q;
00372
00373 p = linep;
00374 while (*p == ' ' || *p == '\t')
00375 p++;
00376 q = buf;
00377 while (*p != ' ' && *p != '\t' && *p != '\0')
00378 *q++ = *p++;
00379 *q = '\0';
00380 linep = p;
00381 return (q > buf);
00382 }
00383
00384
00385 skipbl() {
00386 while (*linep == ' ' || *linep == '\t')
00387 linep++;
00388 }
00389
00390
00391 int
00392 readline() {
00393 register char *p;
00394
00395 if (fgets(line, 1024, infp) == NULL)
00396 return 0;
00397 for (p = line ; *p != '#' && *p != '\n' && *p != '\0' ; p++);
00398 while (p > line && (p[-1] == ' ' || p[-1] == '\t'))
00399 p--;
00400 *p = '\0';
00401 linep = line;
00402 linno++;
00403 if (p - line > BUFLEN)
00404 error("Line too long");
00405 return 1;
00406 }
00407
00408
00409
00410 error(msg, a1, a2, a3, a4, a5, a6)
00411 char *msg;
00412 {
00413 fprintf(stderr, "line %d: ", linno);
00414 fprintf(stderr, msg, a1, a2, a3, a4, a5, a6);
00415 putc('\n', stderr);
00416 exit(2);
00417 }
00418
00419
00420
00421 char *
00422 savestr(s)
00423 char *s;
00424 {
00425 register char *p;
00426 char *malloc();
00427
00428 if ((p = malloc(strlen(s) + 1)) == NULL)
00429 error("Out of space");
00430 strcpy(p, s);
00431 return p;
00432 }