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"
21 extern char *current_token
;
22 extern int table_number
, current
;
24 char *table_name
= NULL
;
25 FILE *hfile
= NULL
, *cfile
= NULL
, *msfile
= NULL
;
41 xmalloc(unsigned int size
)
43 char *p
= malloc(size
);
52 check_arg(char const *const *str_list
, char const *arg
)
55 if (!strcmp(arg
, *str_list
++))
60 static const char *const debug_args
[] = {
66 static const char *const lang_args
[] = {
72 static const char *const prefix_args
[] = {
78 static const char *const emit_args
[] = {
84 static const char *const language_names
[] = {
91 static const char *const c_src_prolog
[] = {
92 "#include <afs/error_table.h>\n",
93 "static const char * const text[] = {\n",
97 static const char *const krc_src_prolog
[] = {
99 "#define NOARGS void\n",
104 "#include <afs/param.h>\n",
105 "#include <afs/error_table.h>\n",
106 "static const char * const text[] = {\n",
110 static const char warning
[] =
111 "/*\n * %s:\n * This file is automatically generated; please do not edit it.\n */\n";
113 static const char msf_warning
[] =
114 "$ \n$ %s:\n$ This file is automatically generated; please do not edit it.\n$ \n$set 1\n";
117 char c_file
[MAXPATHLEN
]; /* output file */
118 char h_file
[MAXPATHLEN
]; /* output */
119 char msf_file
[MAXPATHLEN
];
125 "%s: usage: %s ERROR_TABLE [-debug] [-language LANG] [-h INCLUDE] [-p PREFIX] [-v VERSION] [-emit source|header]\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
)
145 char const *const *cpp
;
146 int got_language
= 0;
147 char *got_include
= 0;
148 char *got_prefix
= ".";
154 * The following signal action for AIX is necessary so that in case of a
155 * crash (i.e. core is generated) we can include the user's data section
156 * in the core dump. Unfortunately, by default, only a partial core is
157 * generated which, in many cases, isn't too useful.
159 struct sigaction nsa
;
161 sigemptyset(&nsa
.sa_mask
);
162 nsa
.sa_handler
= SIG_DFL
;
163 nsa
.sa_flags
= SA_FULLDUMP
;
164 sigaction(SIGSEGV
, &nsa
, NULL
);
166 /* argument parsing */
170 p
= strrchr(whoami
, '/');
177 dup_err("filenames", filename
, arg
);
181 if (check_arg(debug_args
, arg
))
183 else if (check_arg(lang_args
, arg
)) {
190 dup_err("languanges", language_names
[(int)language
], arg
);
192 #define check_lang(x,v) if (!strcasecmp(arg,x)) language = v
193 check_lang("c", lang_C
);
194 check_lang("ansi_c", lang_C
);
195 check_lang("ansi-c", lang_C
);
196 check_lang("krc", lang_KRC
);
197 check_lang("kr_c", lang_KRC
);
198 check_lang("kr-c", lang_KRC
);
199 check_lang("k&r-c", lang_KRC
);
200 check_lang("k&r_c", lang_KRC
);
201 check_lang("c++", lang_CPP
);
202 check_lang("cplusplus", lang_CPP
);
203 check_lang("c-plus-plus", lang_CPP
);
207 fprintf(stderr
, "%s: unknown language name `%s'\n",
209 fprintf(stderr
, "\tpick one of: C K&R-C\n");
212 } else if (strcmp(arg
, "h") == 0) {
218 } else if (check_arg(prefix_args
, arg
)) {
224 } else if (strcmp(arg
, "v") == 0) {
228 fprintf(stderr
, "%s: -v option requires an argument\n",
234 if (version
!= 1 && version
!= 2) {
235 fprintf(stderr
, "%s: unknown control argument -`%s'\n",
242 } else if (check_arg(emit_args
, arg
)) {
246 if (!strcasecmp(arg
, "source")) {
248 } else if (!strcasecmp(arg
, "c")) {
250 } else if (!strcasecmp(arg
, "header")) {
252 } else if (!strcasecmp(arg
, "h")) {
255 fprintf(stderr
, "%s: unknown emit argument - `%s'\n",
261 fprintf(stderr
, "%s: unknown control argument -`%s'\n",
271 else if (language
== lang_CPP
) {
272 fprintf(stderr
, "%s: Sorry, C++ support is not yet finished.\n",
278 emit_source
= emit_header
= 1; /* generate both by default */
281 p
= strrchr(filename
, '/');
286 ename
= xmalloc(strlen(p
) + 5);
289 /* Now, flush .et suffix if it exists. */
290 p
= strrchr(ename
, '.');
292 if (strcmp(p
, ".et") == 0)
298 sprintf(msf_file
, "%s.msf", ename
);
300 sprintf(c_file
, "%s.c", ename
);
305 sprintf(h_file
, "%s.h", got_include
);
307 sprintf(h_file
, "%s.h", ename
);
310 p
= strrchr(filename
, '.');
312 p
= xmalloc(strlen(filename
) + 4);
313 sprintf(p
, "%s.et", filename
);
317 if (asprintf(&et_file
, "%s/%s", got_prefix
, filename
) < 0) {
318 fprintf(stderr
, "Couldn't allocate memory for filename\n");
322 yyin
= fopen(et_file
, "r");
330 /* on NT, yyout is not initialized to stdout */
336 hfile
= fopen(h_file
, "w");
341 fprintf(hfile
, warning
, h_file
);
343 if (emit_header
&& got_include
) {
345 char prolog_h_file
[MAXPATHLEN
];
349 strcpy(prolog_h_file
, got_prefix
);
350 strcat(prolog_h_file
, "/");
351 strcat(prolog_h_file
, got_include
);
352 strcat(prolog_h_file
, ".p.h");
353 prolog_hfile
= fopen(prolog_h_file
, "r");
355 fprintf(stderr
, "Including %s at beginning of %s file.\n",
356 prolog_h_file
, h_file
);
357 fprintf(hfile
, "/* Including %s at beginning of %s file. */\n\n",
358 prolog_h_file
, h_file
);
361 fread(buffer
, sizeof(char), sizeof(buffer
), prolog_hfile
);
363 perror(prolog_h_file
);
366 written
= fwrite(buffer
, sizeof(char), count
, hfile
);
367 if (count
!= written
) {
368 perror(prolog_h_file
);
372 fprintf(hfile
, "\n/* End of prolog file %s. */\n\n",
377 if (emit_source
&& use_msf
) {
378 msfile
= fopen(msf_file
, "w");
379 if (msfile
== NULL
) {
383 fprintf(msfile
, msf_warning
, msf_file
);
384 } else if (emit_source
) {
385 cfile
= fopen(c_file
, "w");
390 fprintf(cfile
, warning
, c_file
);
393 if (language
== lang_C
)
395 else if (language
== lang_KRC
)
396 cpp
= krc_src_prolog
;
400 fputs(*cpp
++, cfile
);
405 fclose(yyin
); /* bye bye input file */
409 fputs(" 0\n};\n\n", cfile
);
411 "static const struct error_table et = { text, %ldL, %d };\n\n",
412 (long int)table_number
, current
);
413 fputs("static struct et_list etlink = { 0, &et};\n\n", cfile
);
414 fprintf(cfile
, "void initialize_%s_error_table(void) {\n",
416 fputs(" afs_add_to_error_table(&etlink);\n", cfile
);
421 fprintf(hfile
, "extern void initialize_%s_error_table(void);\n",
426 fprintf(hfile
, "#define initialize_%s_error_table(void)\n",
432 fprintf(hfile
, "#define ERROR_TABLE_BASE_%s (%ldL)\n", table_name
,
433 (long int)table_number
);
434 /* compatibility... */
435 fprintf(hfile
, "\n/* for compatibility with older versions... */\n");
436 fprintf(hfile
, "#define init_%s_err_tbl initialize_%s_error_table\n",
437 table_name
, table_name
);
438 fprintf(hfile
, "#define %s_err_base ERROR_TABLE_BASE_%s\n",
439 table_name
, table_name
);
440 fprintf(hfile
, "\n/* for compatibility with other users... */\n");
441 lcstring(lcname
, table_name
, sizeof(lcname
));
442 fprintf(hfile
, "#define ERROR_TABLE_BASE_%s (%ldL)\n", lcname
,
443 (long int)table_number
);
444 fprintf(hfile
, "#define init_%s_err_tbl initialize_%s_error_table\n",
447 "#define initialize_%s_error_table initialize_%s_error_table\n",
449 fprintf(hfile
, "#define %s_err_base ERROR_TABLE_BASE_%s\n", lcname
,
451 fclose(hfile
); /* bye bye include file */
459 yyerror(const char *s
)
462 fprintf(stderr
, "\nLine number %d; last token was '%s'\n", yylineno
,