mknodes.c

Go to the documentation of this file.
00001 /*-
00002  * Copyright (c) 1991 The Regents of the University of California.
00003  * All rights reserved.
00004  *
00005  * This code is derived from software contributed to Berkeley by
00006  * Kenneth Almquist.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. All advertising materials mentioning features or use of this software
00017  *    must display the following acknowledgement:
00018  *      This product includes software developed by the University of
00019  *      California, Berkeley and its contributors.
00020  * 4. Neither the name of the University nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
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 /* not lint */
00042 
00043 #ifndef lint
00044 static char sccsid[] = "@(#)mknodes.c   5.1 (Berkeley) 3/7/91";
00045 #endif /* not lint */
00046 
00047 /*
00048  * This program reads the nodetypes file and nodes.c.pat file.  It generates
00049  * the files nodes.h and nodes.c.
00050  */
00051 
00052 #include <stdio.h>
00053 
00054 
00055 #define MAXTYPES 50             /* max number of node types */
00056 #define MAXFIELDS 20            /* max fields in a structure */
00057 #define BUFLEN 100              /* size of character buffers */
00058 
00059 /* field types */
00060 #define T_NODE 1                /* union node *field */
00061 #define T_NODELIST 2            /* struct nodelist *field */
00062 #define T_STRING 3
00063 #define T_INT 4                 /* int field */
00064 #define T_OTHER 5               /* other */
00065 #define T_TEMP 6                /* don't copy this field */
00066 
00067 
00068 struct field {                  /* a structure field */
00069         char *name;             /* name of field */
00070         int type;                       /* type of field */
00071         char *decl;             /* declaration of field */
00072 };
00073 
00074 
00075 struct str {                    /* struct representing a node structure */
00076         char *tag;              /* structure tag */
00077         int nfields;            /* number of fields in the structure */
00078         struct field field[MAXFIELDS];  /* the fields of the structure */
00079         int done;                       /* set if fully parsed */
00080 };
00081 
00082 
00083 int ntypes;                     /* number of node types */
00084 char *nodename[MAXTYPES];       /* names of the nodes */
00085 struct str *nodestr[MAXTYPES];  /* type of structure used by the node */
00086 int nstr;                       /* number of structures */
00087 struct str str[MAXTYPES];       /* the structures */
00088 struct str *curstr;             /* current structure */
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 }

Generated on Fri Apr 14 22:56:41 2006 for minix by  doxygen 1.4.6