comerr-get-rid-of-compile-warnings-20010602
[openafs.git] / src / comerr / 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-cr.h".
7  *
8  */
9
10 #undef MEMORYLEAK
11 #include <afs/param.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14
15 #ifndef AFS_NT40_ENV
16 #include <sys/file.h>
17 #include <sys/param.h>
18 #endif
19
20 #include <errno.h>
21 #include <string.h>
22 #ifdef  AFS_AIX32_ENV
23 #include <signal.h>
24 #endif
25 #include "mit-sipb-cr.h"
26 #include "compiler.h"
27
28 #ifndef lint
29 static const char copyright[] =
30     "Copyright 1987,1988 by MIT Student Information Processing Board";
31 #endif
32
33 extern char *gensym();
34 extern char *current_token;
35 extern int table_number, current;
36 char buffer[BUFSIZ];
37 char *table_name = (char *)NULL;
38 FILE *hfile, *cfile, *msfile;
39 int version = 1;
40 int use_msf = 0;
41
42 /* lex stuff */
43 extern FILE *yyin;
44 extern FILE *yyout;
45 extern int yylineno;
46
47 char * xmalloc (size) unsigned int size; {
48     char * p = malloc (size);
49     if (!p) {
50         perror (whoami);
51         exit (1);
52     }
53     return p;
54 }
55
56 static int check_arg (str_list, arg) char const *const *str_list, *arg; {
57     while (*str_list)
58         if (!strcmp(arg, *str_list++))
59             return 1;
60     return 0;
61 }
62
63 static const char *const debug_args[] = {
64     "d",
65     "debug",
66     0,
67 };
68
69 static const char *const lang_args[] = {
70     "lang",
71     "language",
72     0,
73 };
74
75 static const char *const language_names[] = {
76     "C",
77     "K&R C",
78     "C++",
79     0,
80 };
81
82 static const char * const c_src_prolog[] = {
83     "#include <afs/param.h>\n",
84     "#include <afs/error_table.h>\n",
85     "static const char * const text[] = {\n",
86     0,
87 };
88
89 static const char * const krc_src_prolog[] = {
90     "#ifdef __STDC__\n",
91     "#define NOARGS void\n",
92     "#else\n",
93     "#define NOARGS\n",
94     "#define const\n",
95     "#endif\n\n",
96     "#include <afs/param.h>\n",
97     "#include <afs/error_table.h>\n",
98     "static const char * const text[] = {\n",
99     0,
100 };
101
102 static const char warning[] =
103     "/*\n * %s:\n * This file is automatically generated; please do not edit it.\n */\n";
104
105 static const char msf_warning[] =
106     "$ \n$ %s:\n$ This file is automatically generated; please do not edit it.\n$ \n$set 1\n";
107
108 /* pathnames */
109 char c_file[MAXPATHLEN];        /* output file */
110 char h_file[MAXPATHLEN];        /* output */
111 char msf_file[MAXPATHLEN];
112
113 static void usage () {
114     fprintf (stderr, "%s: usage: %s ERROR_TABLE [-debug] [-language LANG] [-h INCLUDE] [-v version]\n",
115              whoami, whoami);
116     exit (1);
117 }
118
119 static void dup_err (type, one, two) char const *type, *one, *two; {
120     fprintf (stderr, "%s: multiple %s specified: `%s' and `%s'\n",
121              whoami, type, one, two);
122     usage ();
123 }
124
125 #include "AFS_component_version_number.c"
126
127 int main (argc, argv) int argc; char **argv; {
128     char *p, *ename;
129     char const * const *cpp;
130     int got_language = 0;
131     char *got_include = 0;
132
133 #ifdef  AFS_AIX32_ENV
134     /*
135      * The following signal action for AIX is necessary so that in case of a 
136      * crash (i.e. core is generated) we can include the user's data section 
137      * in the core dump. Unfortunately, by default, only a partial core is
138      * generated which, in many cases, isn't too useful.
139      */
140     struct sigaction nsa;
141     
142     sigemptyset(&nsa.sa_mask);
143     nsa.sa_handler = SIG_DFL;
144     nsa.sa_flags = SA_FULLDUMP;
145     sigaction(SIGSEGV, &nsa, NULL);
146 #endif
147     /* argument parsing */
148     debug = 0;
149     filename = 0;
150     whoami = argv[0];
151     p = strrchr (whoami, '/');
152     if (p)
153         whoami = p+1;
154     while (argv++, --argc) {
155         char *arg = *argv;
156         if (arg[0] != '-') {
157             if (filename)
158                 dup_err ("filenames", filename, arg);
159             filename = arg;
160         }
161         else {
162             arg++;
163             if (check_arg (debug_args, arg))
164                 debug++;
165             else if (check_arg (lang_args, arg)) {
166                 got_language++;
167                 arg = *++argv, argc--;
168                 if (!arg)
169                     usage ();
170                 if (language)
171                     dup_err ("languanges", language_names[(int)language], arg);
172 #define check_lang(x,v) else if (!strcasecmp(arg,x)) language = v
173                 check_lang ("c", lang_C);
174                 check_lang ("ansi_c", lang_C);
175                 check_lang ("ansi-c", lang_C);
176                 check_lang ("krc", lang_KRC);
177                 check_lang ("kr_c", lang_KRC);
178                 check_lang ("kr-c", lang_KRC);
179                 check_lang ("k&r-c", lang_KRC);
180                 check_lang ("k&r_c", lang_KRC);
181                 check_lang ("c++", lang_CPP);
182                 check_lang ("cplusplus", lang_CPP);
183                 check_lang ("c-plus-plus", lang_CPP);
184 #undef check_lang
185                 else {
186                     fprintf (stderr, "%s: unknown language name `%s'\n",
187                              whoami, arg);
188                     fprintf (stderr, "\tpick one of: C K&R-C\n");
189                     exit (1);
190                 }
191             }
192             else if (strcmp (arg, "h") == 0) {
193                 arg = *++argv, argc--;
194                 if (!arg) usage ();
195                 got_include = arg;
196             }
197             else if (strcmp (arg, "v") == 0) {
198                 arg = *++argv, argc--;
199                 version = atoi(arg);
200                 if (version != 1 && version != 2) {
201                     fprintf (stderr, "%s: unknown control argument -`%s'\n",
202                              whoami, arg);
203                     usage ();
204                     exit(1);
205                 }
206                 if (version == 2) use_msf = 1;
207             }
208             else {
209                 fprintf (stderr, "%s: unknown control argument -`%s'\n",
210                          whoami, arg);
211                 usage ();
212             }
213         }
214     }
215     if (!filename)
216         usage ();
217     if (!got_language)
218         language = lang_C;
219     else if (language == lang_CPP) {
220         fprintf (stderr, "%s: Sorry, C++ support is not yet finished.\n",
221                  whoami);
222         exit (1);
223     }
224
225
226     p = strrchr(filename, '/');
227     if (p == (char *)NULL)
228         p = filename;
229     else
230         p++;
231     ename = xmalloc (strlen(p) + 5);
232     strcpy (ename, p);
233
234     /* Now, flush .et suffix if it exists.   */
235     p = strrchr(ename, '.');
236     if (p != NULL) {
237         if (strcmp (p, ".et") == 0)
238             *p = 0;
239     }
240
241     if (use_msf) {
242         sprintf(msf_file, "%s.msf", ename);
243     }  else {
244         sprintf(c_file, "%s.c", ename);
245     }
246     if (got_include) {
247         sprintf(h_file, "%s.h", got_include);
248     } else {
249         sprintf(h_file, "%s.h", ename);
250     }
251     p = strrchr(filename, '.');
252     if (p == NULL)
253     {
254         p = xmalloc (strlen(filename) + 4);
255         sprintf(p, "%s.et", filename);
256         filename = p;
257     }
258
259     yyin = fopen(filename, "r");
260     if (!yyin) {
261         perror(filename);
262         exit(1);
263     }
264
265     /* on NT, yyout is not initialized to stdout */
266     if (!yyout) {
267         yyout = stdout;
268     }
269
270     hfile = fopen(h_file, "w");
271     if (hfile == (FILE *)NULL) {
272         perror(h_file);
273         exit(1);
274     }
275     fprintf (hfile, warning, h_file);
276     if (got_include) {
277         char  buffer[BUFSIZ];
278         char  prolog_h_file[MAXPATHLEN];
279         FILE *prolog_hfile;
280         int   count, written;
281
282         strcpy (prolog_h_file, got_include);
283         strcat (prolog_h_file, ".p.h");
284         prolog_hfile = fopen(prolog_h_file, "r");
285         if (prolog_hfile) {
286             fprintf (stderr, "Including %s at beginning of %s file.\n", prolog_h_file, h_file);
287             fprintf (hfile, "/* Including %s at beginning of %s file. */\n\n",
288                      prolog_h_file, h_file);
289             do {
290                 count = fread (buffer, sizeof(char), sizeof(buffer), prolog_hfile);
291                 if (count == EOF) {
292                     perror(prolog_h_file);
293                     exit(1);
294                 }
295                 written = fwrite (buffer, sizeof(char), count, hfile);
296                 if (count != written) {
297                     perror(prolog_h_file);
298                     exit(1);
299                 }
300             } while (count > 0);
301             fprintf (hfile, "\n/* End of prolog file %s. */\n\n", prolog_h_file);
302         }
303     }
304
305     if (use_msf) {
306         msfile = fopen(msf_file, "w");
307         if (msfile == (FILE *)NULL) {
308             perror(msf_file);
309             exit(1);
310         }
311         fprintf(msfile, msf_warning, msf_file);
312     } else {
313         cfile = fopen(c_file, "w");
314         if (cfile == (FILE *)NULL) {
315             perror(c_file);
316             exit(1);
317         }
318         fprintf (cfile, warning, c_file);
319
320         /* prologue */
321         if (language == lang_C)
322             cpp = c_src_prolog;
323         else if (language == lang_KRC)
324             cpp = krc_src_prolog;
325         else
326             abort ();
327         while (*cpp)
328             fputs (*cpp++, cfile);
329     }
330
331     /* parse it */
332     yyparse();
333     fclose(yyin);               /* bye bye input file */
334
335     if (!use_msf) {
336         fputs ("    0\n};\n\n", cfile);
337         fprintf(cfile,
338                 "static const struct error_table et = { text, %ldL, %d };\n\n",
339                 (long int) table_number, current);
340         fputs("static struct et_list etlink = { 0, &et};\n\n", cfile);
341         fprintf(cfile, "void initialize_%s_error_table (%s) {\n",
342                 table_name, (language == lang_C) ? "void" : "NOARGS");
343         fputs("    add_to_error_table(&etlink);\n", cfile);
344         fputs("}\n", cfile);
345         fclose(cfile);
346
347
348         fprintf (hfile, "extern void initialize_%s_error_table ();\n",
349                  table_name);
350     } else {
351         fprintf (hfile, "#define initialize_%s_error_table()\n",
352                  table_name);
353     }
354
355     fprintf (hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n",
356              table_name, (long int) table_number);
357     /* compatibility... */
358     fprintf (hfile, "\n/* for compatibility with older versions... */\n");
359     fprintf (hfile, "#define init_%s_err_tbl initialize_%s_error_table\n",
360              table_name, table_name);
361     fprintf (hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", table_name,
362              table_name);
363     fclose(hfile);              /* bye bye include file */
364     if (use_msf)
365         fclose(msfile);
366     return 0;
367 }
368
369 void yyerror(const char *s) {
370     fputs(s, stderr);
371     fprintf(stderr, "\nLine number %d; last token was '%s'\n",
372             yylineno, current_token);
373 }