Annotation of src/usr.bin/compile_et/compile_et.c, Revision 1.1
1.1 ! downsj 1: /* $OpenBSD$ */
! 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[] =
! 26: "$Id: compile_et.c,v 1.1.1.1 1995/12/14 06:52:49 tholo Exp $";
! 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 () {
! 117: fprintf (stderr, "%s: usage: %s ERROR_TABLE\n",
! 118: whoami, whoami);
! 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: }