[BACK]Return to compile_et.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / compile_et

Annotation of src/usr.bin/compile_et/compile_et.c, Revision 1.2

1.2     ! deraadt     1: /*     $OpenBSD: compile_et.c,v 1.1 1996/11/11 05:06:34 downsj Exp $   */
1.1       downsj      2:
                      3: /*
                      4:  * Copyright 1986, 1987, 1988
                      5:  * by MIT Student Information Processing Board.
                      6:  *
                      7:  * For copyright info, see "mit-sipb-copyright.h".
                      8:  */
                      9:
                     10: #include <stdio.h>
                     11: #include <sys/types.h>
                     12: #include <sys/file.h>
                     13: #include <string.h>
                     14: #include <sys/param.h>
                     15: #include "compiler.h"
                     16:
                     17: #ifndef __STDC__
                     18: #define const
                     19: #endif
                     20:
                     21: #ifndef lint
                     22: static const char copyright[] =
                     23:     "Copyright 1987,1988 by MIT Student Information Processing Board";
                     24:
                     25: static const char rcsid_compile_et_c[] =
1.2     ! deraadt    26:     "$Id: compile_et.c,v 1.1 1996/11/11 05:06:34 downsj Exp $";
1.1       downsj     27: #endif
                     28:
                     29: extern char *gensym();
                     30: extern char *current_token;
                     31: extern int table_number, current;
                     32: char buffer[BUFSIZ];
                     33: char *table_name = (char *)NULL;
                     34: FILE *hfile, *cfile;
                     35:
                     36: /* C library */
                     37: extern char *malloc();
                     38: extern int errno;
                     39:
                     40: /* lex stuff */
                     41: extern FILE *yyin;
                     42: extern unsigned lineno;
                     43:
                     44: char * xmalloc (size) unsigned int size; {
                     45:     char * p = malloc (size);
                     46:     if (!p) {
                     47:        perror (whoami);
                     48:        exit (1);
                     49:     }
                     50:     return p;
                     51: }
                     52:
                     53: static int check_arg (str_list, arg) char const *const *str_list, *arg; {
                     54:     while (*str_list)
                     55:        if (!strcmp(arg, *str_list++))
                     56:            return 1;
                     57:     return 0;
                     58: }
                     59:
                     60: static const char *const debug_args[] = {
                     61:     "d",
                     62:     "debug",
                     63:     0,
                     64: };
                     65:
                     66: static const char *const lang_args[] = {
                     67:     "lang",
                     68:     "language",
                     69:     0,
                     70: };
                     71:
                     72: static const char *const language_names[] = {
                     73:     "C",
                     74:     "K&R C",
                     75:     "C++",
                     76:     0,
                     77: };
                     78:
                     79: static const char * const c_src_prolog[] = {
                     80:     "static const char * const text[] = {\n",
                     81:     0,
                     82: };
                     83:
                     84: static const char * const krc_src_prolog[] = {
                     85:     "#ifdef __STDC__\n",
                     86:     "#define NOARGS void\n",
                     87:     "#else\n",
                     88:     "#define NOARGS\n",
                     89:     "#define const\n",
                     90:     "#endif\n\n",
                     91:     "static const char * const text[] = {\n",
                     92:     0,
                     93: };
                     94:
                     95: static const char *const struct_def[] = {
                     96:     "struct error_table {\n",
                     97:     "    char const * const * msgs;\n",
                     98:     "    long base;\n",
                     99:     "    int n_msgs;\n",
                    100:     "};\n",
                    101:     "struct et_list {\n",
                    102:     "    struct et_list *next;\n",
                    103:     "    const struct error_table * table;\n",
                    104:     "};\n",
                    105:     "extern struct et_list *_et_list;\n",
                    106:     "\n", 0,
                    107: };
                    108:
                    109: static const char warning[] =
                    110:     "/*\n * %s:\n * This file is automatically generated; please do not edit it.\n */\n";
                    111:
                    112: /* pathnames */
                    113: char c_file[MAXPATHLEN];       /* output file */
                    114: char h_file[MAXPATHLEN];       /* output */
                    115:
                    116: static void usage () {
1.2     ! deraadt   117:     fprintf (stderr, "usage: %s ERROR_TABLE\n",
        !           118:             whoami);
1.1       downsj    119:     exit (1);
                    120: }
                    121:
                    122: static void dup_err (type, one, two) char const *type, *one, *two; {
                    123:     fprintf (stderr, "%s: multiple %s specified: `%s' and `%s'\n",
                    124:             whoami, type, one, two);
                    125:     usage ();
                    126: }
                    127:
                    128: int main (argc, argv) int argc; char **argv; {
                    129:     char *p, *ename;
                    130:     int len;
                    131:     char const * const *cpp;
                    132:     int got_language = 0;
                    133:
                    134:     /* argument parsing */
                    135:     debug = 0;
                    136:     filename = 0;
                    137:     whoami = argv[0];
                    138:     p = strrchr (whoami, '/');
                    139:     if (p)
                    140:        whoami = p+1;
                    141:     while (argv++, --argc) {
                    142:        char *arg = *argv;
                    143:        if (arg[0] != '-') {
                    144:            if (filename)
                    145:                dup_err ("filenames", filename, arg);
                    146:            filename = arg;
                    147:        }
                    148:        else {
                    149:            arg++;
                    150:            if (check_arg (debug_args, arg))
                    151:                debug++;
                    152:            else if (check_arg (lang_args, arg)) {
                    153:                got_language++;
                    154:                arg = *++argv, argc--;
                    155:                if (!arg)
                    156:                    usage ();
                    157:                if (language)
                    158:                    dup_err ("languanges", language_names[(int)language], arg);
                    159: #define check_lang(x,v) else if (!strcasecmp(arg,x)) language = v
                    160:                check_lang ("c", lang_C);
                    161:                check_lang ("ansi_c", lang_C);
                    162:                check_lang ("ansi-c", lang_C);
                    163:                check_lang ("krc", lang_KRC);
                    164:                check_lang ("kr_c", lang_KRC);
                    165:                check_lang ("kr-c", lang_KRC);
                    166:                check_lang ("k&r-c", lang_KRC);
                    167:                check_lang ("k&r_c", lang_KRC);
                    168:                check_lang ("c++", lang_CPP);
                    169:                check_lang ("cplusplus", lang_CPP);
                    170:                check_lang ("c-plus-plus", lang_CPP);
                    171: #undef check_lang
                    172:                else {
                    173:                    fprintf (stderr, "%s: unknown language name `%s'\n",
                    174:                             whoami, arg);
                    175:                    fprintf (stderr, "\tpick one of: C K&R-C\n");
                    176:                    exit (1);
                    177:                }
                    178:            }
                    179:            else {
                    180:                fprintf (stderr, "%s: unknown control argument -`%s'\n",
                    181:                         whoami, arg);
                    182:                usage ();
                    183:            }
                    184:        }
                    185:     }
                    186:     if (!filename)
                    187:        usage ();
                    188:     if (!got_language)
                    189:        language = lang_KRC;
                    190:     else if (language == lang_CPP) {
                    191:        fprintf (stderr, "%s: Sorry, C++ support is not yet finished.\n",
                    192:                 whoami);
                    193:        exit (1);
                    194:     }
                    195:
                    196:     p = xmalloc (strlen (filename) + 5);
                    197:     strcpy (p, filename);
                    198:     filename = p;
                    199:     p = strrchr(filename, '/');
                    200:     if (p == (char *)NULL)
                    201:        p = filename;
                    202:     else
                    203:        p++;
                    204:     ename = p;
                    205:     len = strlen (ename);
                    206:     p += len - 3;
                    207:     if (strcmp (p, ".et"))
                    208:        p += 3;
                    209:     *p++ = '.';
                    210:     /* now p points to where "et" suffix should start */
                    211:     /* generate new filenames */
                    212:     strcpy (p, "c");
                    213:     strcpy (c_file, ename);
                    214:     *p = 'h';
                    215:     strcpy (h_file, ename);
                    216:     strcpy (p, "et");
                    217:
                    218:     yyin = fopen(filename, "r");
                    219:     if (!yyin) {
                    220:        perror(filename);
                    221:        exit(1);
                    222:     }
                    223:
                    224:     hfile = fopen(h_file, "w");
                    225:     if (hfile == (FILE *)NULL) {
                    226:        perror(h_file);
                    227:        exit(1);
                    228:     }
                    229:     fprintf (hfile, warning, h_file);
                    230:
                    231:     cfile = fopen(c_file, "w");
                    232:     if (cfile == (FILE *)NULL) {
                    233:        perror(c_file);
                    234:        exit(1);
                    235:     }
                    236:     fprintf (cfile, warning, c_file);
                    237:
                    238:     /* prologue */
                    239:     if (language == lang_C)
                    240:        cpp = c_src_prolog;
                    241:     else if (language == lang_KRC)
                    242:        cpp = krc_src_prolog;
                    243:     else
                    244:        abort ();
                    245:     while (*cpp)
                    246:        fputs (*cpp++, cfile);
                    247:
                    248:     /* parse it */
                    249:     yyparse();
                    250:     fclose(yyin);              /* bye bye input file */
                    251:
                    252:     fputs ("    0\n};\n\n", cfile);
                    253:     for (cpp = struct_def; *cpp; cpp++)
                    254:        fputs (*cpp, cfile);
                    255:     fprintf(cfile,
                    256:            "static const struct error_table et = { text, %ldL, %d };\n\n",
                    257:            table_number, current);
                    258:     fputs("static struct et_list link = { 0, 0 };\n\n",
                    259:          cfile);
                    260:     fprintf(cfile, "void initialize_%s_error_table (%s) {\n",
                    261:            table_name, (language == lang_C) ? "void" : "NOARGS");
                    262:     fputs("    if (!link.table) {\n", cfile);
                    263:     fputs("        link.next = _et_list;\n", cfile);
                    264:     fputs("        link.table = &et;\n", cfile);
                    265:     fputs("        _et_list = &link;\n", cfile);
                    266:     fputs("    }\n", cfile);
                    267:     fputs("}\n", cfile);
                    268:     fclose(cfile);
                    269:
                    270:     fprintf (hfile, "extern void initialize_%s_error_table ();\n",
                    271:             table_name);
                    272:     fprintf (hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n",
                    273:             table_name, table_number);
                    274:     /* compatibility... */
                    275:     fprintf (hfile, "\n/* for compatibility with older versions... */\n");
                    276:     fprintf (hfile, "#define init_%s_err_tbl initialize_%s_error_table\n",
                    277:             table_name, table_name);
                    278:     fprintf (hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", table_name,
                    279:             table_name);
                    280:     fclose(hfile);             /* bye bye include file */
                    281:
                    282:     return 0;
                    283: }
                    284:
                    285: int yyerror(s) char *s; {
                    286:     fputs(s, stderr);
                    287:     fprintf(stderr, "\nLine number %d; last token was '%s'\n",
                    288:            lineno, current_token);
                    289: }