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, *cfile, *msfile;
44 xmalloc(unsigned int size)
46 char *p = malloc(size);
55 check_arg(char const *const *str_list, char const *arg)
58 if (!strcmp(arg, *str_list++))
63 static const char *const debug_args[] = {
69 static const char *const lang_args[] = {
75 static const char *const prefix_args[] = {
81 static const char *const language_names[] = {
88 static const char *const c_src_prolog[] = {
89 "#include <afsconfig.h>\n",
90 "#include <afs/param.h>\n",
91 "#include <afs/error_table.h>\n",
92 "static const char * const text[] = {\n",
96 static const char *const krc_src_prolog[] = {
98 "#define NOARGS void\n",
103 "#include <afs/param.h>\n",
104 "#include <afs/error_table.h>\n",
105 "static const char * const text[] = {\n",
109 static const char warning[] =
110 "/*\n * %s:\n * This file is automatically generated; please do not edit it.\n */\n";
112 static const char msf_warning[] =
113 "$ \n$ %s:\n$ This file is automatically generated; please do not edit it.\n$ \n$set 1\n";
116 char c_file[MAXPATHLEN]; /* output file */
117 char h_file[MAXPATHLEN]; /* output */
118 char msf_file[MAXPATHLEN];
119 char et_file[MAXPATHLEN]; /* full path to input file */
125 "%s: usage: %s ERROR_TABLE [-debug] [-language LANG] [-h INCLUDE] [-p prefix] [-v version]\n",
131 dup_err(char const *type, char const *one, char const *two)
133 fprintf(stderr, "%s: multiple %s specified: `%s' and `%s'\n", whoami,
138 #include "AFS_component_version_number.c"
141 main(int argc, char **argv)
144 char const *const *cpp;
145 int got_language = 0;
146 char *got_include = 0;
147 char *got_prefix = ".";
152 * The following signal action for AIX is necessary so that in case of a
153 * crash (i.e. core is generated) we can include the user's data section
154 * in the core dump. Unfortunately, by default, only a partial core is
155 * generated which, in many cases, isn't too useful.
157 struct sigaction nsa;
159 sigemptyset(&nsa.sa_mask);
160 nsa.sa_handler = SIG_DFL;
161 nsa.sa_flags = SA_FULLDUMP;
162 sigaction(SIGSEGV, &nsa, NULL);
164 /* argument parsing */
168 p = strrchr(whoami, '/');
175 dup_err("filenames", filename, arg);
179 if (check_arg(debug_args, arg))
181 else if (check_arg(lang_args, arg)) {
188 dup_err("languanges", language_names[(int)language], arg);
190 #define check_lang(x,v) if (!strcasecmp(arg,x)) language = v
191 check_lang("c", lang_C);
192 check_lang("ansi_c", lang_C);
193 check_lang("ansi-c", lang_C);
194 check_lang("krc", lang_KRC);
195 check_lang("kr_c", lang_KRC);
196 check_lang("kr-c", lang_KRC);
197 check_lang("k&r-c", lang_KRC);
198 check_lang("k&r_c", lang_KRC);
199 check_lang("c++", lang_CPP);
200 check_lang("cplusplus", lang_CPP);
201 check_lang("c-plus-plus", lang_CPP);
205 fprintf(stderr, "%s: unknown language name `%s'\n",
207 fprintf(stderr, "\tpick one of: C K&R-C\n");
210 } else if (strcmp(arg, "h") == 0) {
216 } else if (check_arg(prefix_args, arg)) {
222 } else if (strcmp(arg, "v") == 0) {
226 fprintf(stderr, "%s: -v option requires an argument\n",
232 if (version != 1 && version != 2) {
233 fprintf(stderr, "%s: unknown control argument -`%s'\n",
241 fprintf(stderr, "%s: unknown control argument -`%s'\n",
251 else if (language == lang_CPP) {
252 fprintf(stderr, "%s: Sorry, C++ support is not yet finished.\n",
258 p = strrchr(filename, '/');
263 ename = xmalloc(strlen(p) + 5);
266 /* Now, flush .et suffix if it exists. */
267 p = strrchr(ename, '.');
269 if (strcmp(p, ".et") == 0)
274 sprintf(msf_file, "%s.msf", ename);
276 sprintf(c_file, "%s.c", ename);
279 sprintf(h_file, "%s.h", got_include);
281 sprintf(h_file, "%s.h", ename);
283 p = strrchr(filename, '.');
285 p = xmalloc(strlen(filename) + 4);
286 sprintf(p, "%s.et", filename);
290 sprintf(et_file, "%s/%s", got_prefix, filename);
292 yyin = fopen(et_file, "r");
298 /* on NT, yyout is not initialized to stdout */
303 hfile = fopen(h_file, "w");
308 fprintf(hfile, warning, h_file);
311 char prolog_h_file[MAXPATHLEN];
315 strcpy(prolog_h_file, got_prefix);
316 strcat(prolog_h_file, "/");
317 strcat(prolog_h_file, got_include);
318 strcat(prolog_h_file, ".p.h");
319 prolog_hfile = fopen(prolog_h_file, "r");
321 fprintf(stderr, "Including %s at beginning of %s file.\n",
322 prolog_h_file, h_file);
323 fprintf(hfile, "/* Including %s at beginning of %s file. */\n\n",
324 prolog_h_file, h_file);
327 fread(buffer, sizeof(char), sizeof(buffer), prolog_hfile);
329 perror(prolog_h_file);
332 written = fwrite(buffer, sizeof(char), count, hfile);
333 if (count != written) {
334 perror(prolog_h_file);
338 fprintf(hfile, "\n/* End of prolog file %s. */\n\n",
344 msfile = fopen(msf_file, "w");
345 if (msfile == NULL) {
349 fprintf(msfile, msf_warning, msf_file);
351 cfile = fopen(c_file, "w");
356 fprintf(cfile, warning, c_file);
359 if (language == lang_C)
361 else if (language == lang_KRC)
362 cpp = krc_src_prolog;
366 fputs(*cpp++, cfile);
371 fclose(yyin); /* bye bye input file */
374 fputs(" 0\n};\n\n", cfile);
376 "static const struct error_table et = { text, %ldL, %d };\n\n",
377 (long int)table_number, current);
378 fputs("static struct et_list etlink = { 0, &et};\n\n", cfile);
379 fprintf(cfile, "void initialize_%s_error_table(void) {\n",
381 fputs(" afs_add_to_error_table(&etlink);\n", cfile);
386 fprintf(hfile, "extern void initialize_%s_error_table(void);\n",
389 fprintf(hfile, "#define initialize_%s_error_table(void)\n",
393 fprintf(hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n", table_name,
394 (long int)table_number);
395 /* compatibility... */
396 fprintf(hfile, "\n/* for compatibility with older versions... */\n");
397 fprintf(hfile, "#define init_%s_err_tbl initialize_%s_error_table\n",
398 table_name, table_name);
399 fprintf(hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", table_name,
401 fprintf(hfile, "\n/* for compatibility with other users... */\n");
402 lcstring(lcname, table_name, sizeof(lcname));
403 fprintf(hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n", lcname,
404 (long int)table_number);
405 fprintf(hfile, "#define init_%s_err_tbl initialize_%s_error_table\n",
408 "#define initialize_%s_error_table initialize_%s_error_table\n",
410 fprintf(hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", lcname,
412 fclose(hfile); /* bye bye include file */
419 yyerror(const char *s)
422 fprintf(stderr, "\nLine number %d; last token was '%s'\n", yylineno,