3 * Copyright 1986, 1987, 1988
4 * by MIT Student Information Processing Board.
6 * For copyright info, see "mit-sipb-cr.h".
11 #include <afsconfig.h>
12 #include <afs/param.h>
17 #include "mit-sipb-cr.h"
22 static const char copyright[] =
23 "Copyright 1987,1988 by MIT Student Information Processing Board";
26 extern char *current_token;
27 extern int table_number, current;
29 char *table_name = NULL;
30 FILE *hfile = NULL, *cfile = NULL, *msfile = NULL;
46 xmalloc(unsigned int size)
48 char *p = malloc(size);
57 check_arg(char const *const *str_list, char const *arg)
60 if (!strcmp(arg, *str_list++))
65 static const char *const debug_args[] = {
71 static const char *const lang_args[] = {
77 static const char *const prefix_args[] = {
83 static const char *const emit_args[] = {
89 static const char *const language_names[] = {
96 static const char *const c_src_prolog[] = {
97 "#include <afsconfig.h>\n",
98 "#include <afs/param.h>\n",
99 "#include <afs/error_table.h>\n",
100 "static const char * const text[] = {\n",
104 static const char *const krc_src_prolog[] = {
106 "#define NOARGS void\n",
111 "#include <afs/param.h>\n",
112 "#include <afs/error_table.h>\n",
113 "static const char * const text[] = {\n",
117 static const char warning[] =
118 "/*\n * %s:\n * This file is automatically generated; please do not edit it.\n */\n";
120 static const char msf_warning[] =
121 "$ \n$ %s:\n$ This file is automatically generated; please do not edit it.\n$ \n$set 1\n";
124 char c_file[MAXPATHLEN]; /* output file */
125 char h_file[MAXPATHLEN]; /* output */
126 char msf_file[MAXPATHLEN];
127 char et_file[MAXPATHLEN]; /* full path to input file */
133 "%s: usage: %s ERROR_TABLE [-debug] [-language LANG] [-h INCLUDE] [-p PREFIX] [-v VERSION] [-emit source|header]\n",
139 dup_err(char const *type, char const *one, char const *two)
141 fprintf(stderr, "%s: multiple %s specified: `%s' and `%s'\n", whoami,
146 #include "AFS_component_version_number.c"
149 main(int argc, char **argv)
152 char const *const *cpp;
153 int got_language = 0;
154 char *got_include = 0;
155 char *got_prefix = ".";
161 * The following signal action for AIX is necessary so that in case of a
162 * crash (i.e. core is generated) we can include the user's data section
163 * in the core dump. Unfortunately, by default, only a partial core is
164 * generated which, in many cases, isn't too useful.
166 struct sigaction nsa;
168 sigemptyset(&nsa.sa_mask);
169 nsa.sa_handler = SIG_DFL;
170 nsa.sa_flags = SA_FULLDUMP;
171 sigaction(SIGSEGV, &nsa, NULL);
173 /* argument parsing */
177 p = strrchr(whoami, '/');
184 dup_err("filenames", filename, arg);
188 if (check_arg(debug_args, arg))
190 else if (check_arg(lang_args, arg)) {
197 dup_err("languanges", language_names[(int)language], arg);
199 #define check_lang(x,v) if (!strcasecmp(arg,x)) language = v
200 check_lang("c", lang_C);
201 check_lang("ansi_c", lang_C);
202 check_lang("ansi-c", lang_C);
203 check_lang("krc", lang_KRC);
204 check_lang("kr_c", lang_KRC);
205 check_lang("kr-c", lang_KRC);
206 check_lang("k&r-c", lang_KRC);
207 check_lang("k&r_c", lang_KRC);
208 check_lang("c++", lang_CPP);
209 check_lang("cplusplus", lang_CPP);
210 check_lang("c-plus-plus", lang_CPP);
214 fprintf(stderr, "%s: unknown language name `%s'\n",
216 fprintf(stderr, "\tpick one of: C K&R-C\n");
219 } else if (strcmp(arg, "h") == 0) {
225 } else if (check_arg(prefix_args, arg)) {
231 } else if (strcmp(arg, "v") == 0) {
235 fprintf(stderr, "%s: -v option requires an argument\n",
241 if (version != 1 && version != 2) {
242 fprintf(stderr, "%s: unknown control argument -`%s'\n",
249 } else if (check_arg(emit_args, arg)) {
253 if (!strcasecmp(arg, "source")) {
255 } else if (!strcasecmp(arg, "c")) {
257 } else if (!strcasecmp(arg, "header")) {
259 } else if (!strcasecmp(arg, "h")) {
262 fprintf(stderr, "%s: unknown emit argument - `%s'\n",
268 fprintf(stderr, "%s: unknown control argument -`%s'\n",
278 else if (language == lang_CPP) {
279 fprintf(stderr, "%s: Sorry, C++ support is not yet finished.\n",
285 emit_source = emit_header = 1; /* generate both by default */
288 p = strrchr(filename, '/');
293 ename = xmalloc(strlen(p) + 5);
296 /* Now, flush .et suffix if it exists. */
297 p = strrchr(ename, '.');
299 if (strcmp(p, ".et") == 0)
305 sprintf(msf_file, "%s.msf", ename);
307 sprintf(c_file, "%s.c", ename);
312 sprintf(h_file, "%s.h", got_include);
314 sprintf(h_file, "%s.h", ename);
317 p = strrchr(filename, '.');
319 p = xmalloc(strlen(filename) + 4);
320 sprintf(p, "%s.et", filename);
324 sprintf(et_file, "%s/%s", got_prefix, filename);
326 yyin = fopen(et_file, "r");
332 /* on NT, yyout is not initialized to stdout */
338 hfile = fopen(h_file, "w");
343 fprintf(hfile, warning, h_file);
345 if (emit_header && got_include) {
347 char prolog_h_file[MAXPATHLEN];
351 strcpy(prolog_h_file, got_prefix);
352 strcat(prolog_h_file, "/");
353 strcat(prolog_h_file, got_include);
354 strcat(prolog_h_file, ".p.h");
355 prolog_hfile = fopen(prolog_h_file, "r");
357 fprintf(stderr, "Including %s at beginning of %s file.\n",
358 prolog_h_file, h_file);
359 fprintf(hfile, "/* Including %s at beginning of %s file. */\n\n",
360 prolog_h_file, h_file);
363 fread(buffer, sizeof(char), sizeof(buffer), prolog_hfile);
365 perror(prolog_h_file);
368 written = fwrite(buffer, sizeof(char), count, hfile);
369 if (count != written) {
370 perror(prolog_h_file);
374 fprintf(hfile, "\n/* End of prolog file %s. */\n\n",
379 if (emit_source && use_msf) {
380 msfile = fopen(msf_file, "w");
381 if (msfile == NULL) {
385 fprintf(msfile, msf_warning, msf_file);
386 } else if (emit_source) {
387 cfile = fopen(c_file, "w");
392 fprintf(cfile, warning, c_file);
395 if (language == lang_C)
397 else if (language == lang_KRC)
398 cpp = krc_src_prolog;
402 fputs(*cpp++, cfile);
407 fclose(yyin); /* bye bye input file */
411 fputs(" 0\n};\n\n", cfile);
413 "static const struct error_table et = { text, %ldL, %d };\n\n",
414 (long int)table_number, current);
415 fputs("static struct et_list etlink = { 0, &et};\n\n", cfile);
416 fprintf(cfile, "void initialize_%s_error_table(void) {\n",
418 fputs(" afs_add_to_error_table(&etlink);\n", cfile);
423 fprintf(hfile, "extern void initialize_%s_error_table(void);\n",
428 fprintf(hfile, "#define initialize_%s_error_table(void)\n",
434 fprintf(hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n", table_name,
435 (long int)table_number);
436 /* compatibility... */
437 fprintf(hfile, "\n/* for compatibility with older versions... */\n");
438 fprintf(hfile, "#define init_%s_err_tbl initialize_%s_error_table\n",
439 table_name, table_name);
440 fprintf(hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n",
441 table_name, table_name);
442 fprintf(hfile, "\n/* for compatibility with other users... */\n");
443 lcstring(lcname, table_name, sizeof(lcname));
444 fprintf(hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n", lcname,
445 (long int)table_number);
446 fprintf(hfile, "#define init_%s_err_tbl initialize_%s_error_table\n",
449 "#define initialize_%s_error_table initialize_%s_error_table\n",
451 fprintf(hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", lcname,
453 fclose(hfile); /* bye bye include file */
461 yyerror(const char *s)
464 fprintf(stderr, "\nLine number %d; last token was '%s'\n", yylineno,