Annotation of src/usr.bin/compile_et/compile_et.c, Revision 1.3
1.3 ! kstailey 1: /* $OpenBSD: compile_et.c,v 1.2 1996/12/11 13:44:56 deraadt 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.3 ! kstailey 26: "$Id: compile_et.c,v 1.2 1996/12/11 13:44:56 deraadt 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];
1.3 ! kstailey 33: char *table_name = NULL;
1.1 downsj 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, '/');
1.3 ! kstailey 200: if (p == NULL)
1.1 downsj 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");
1.3 ! kstailey 225: if (hfile == NULL) {
1.1 downsj 226: perror(h_file);
227: exit(1);
228: }
229: fprintf (hfile, warning, h_file);
230:
231: cfile = fopen(c_file, "w");
1.3 ! kstailey 232: if (cfile == NULL) {
1.1 downsj 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,
1.3 ! kstailey 256: "static const struct error_table et = { text, %dL, %d };\n\n",
1.1 downsj 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);
1.3 ! kstailey 272: fprintf (hfile, "#define ERROR_TABLE_BASE_%s (%dL)\n",
1.1 downsj 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);
1.3 ! kstailey 289:
! 290: return 0;
1.1 downsj 291: }