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