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