150764Smarkm/*
2233294Sstas * Copyright (c) 1998-2002 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
550764Smarkm *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
950764Smarkm *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1250764Smarkm *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
1650764Smarkm *
17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
18233294Sstas *    may be used to endorse or promote products derived from this software
19233294Sstas *    without specific prior written permission.
2050764Smarkm *
21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31233294Sstas * SUCH DAMAGE.
3250764Smarkm */
3350764Smarkm
3450764Smarkm#undef ROKEN_RENAME
35233294Sstas
36233294Sstas#define	rk_PATH_DELIM	'/'
37233294Sstas
3850764Smarkm#include "compile_et.h"
3950764Smarkm#include <getarg.h>
4050764Smarkm
41233294Sstas#include <roken.h>
4250764Smarkm#include <err.h>
4350764Smarkm#include "parse.h"
4450764Smarkm
4550764Smarkmint numerror;
4650764Smarkmextern FILE *yyin;
4750764Smarkm
4850764Smarkmextern void yyparse(void);
4950764Smarkm
50178846Sdfrlong base_id;
5150764Smarkmint number;
5250764Smarkmchar *prefix;
5350764Smarkmchar *id_str;
5450764Smarkm
5550764Smarkmchar name[128];
5650764Smarkmchar Basename[128];
5750764Smarkm
5850764Smarkm#ifdef YYDEBUG
5950764Smarkmextern int yydebug = 1;
6050764Smarkm#endif
6150764Smarkm
6250764Smarkmchar *filename;
6350764Smarkmchar hfn[128];
6450764Smarkmchar cfn[128];
6550764Smarkm
6650764Smarkmstruct error_code *codes = NULL;
6750764Smarkm
6850764Smarkmstatic int
6950764Smarkmgenerate_c(void)
7050764Smarkm{
7150764Smarkm    int n;
7250764Smarkm    struct error_code *ec;
7350764Smarkm
7450764Smarkm    FILE *c_file = fopen(cfn, "w");
7550764Smarkm    if(c_file == NULL)
7650764Smarkm	return 1;
7750764Smarkm
7850764Smarkm    fprintf(c_file, "/* Generated from %s */\n", filename);
79233294Sstas    if(id_str)
8050764Smarkm	fprintf(c_file, "/* %s */\n", id_str);
8150764Smarkm    fprintf(c_file, "\n");
8250764Smarkm    fprintf(c_file, "#include <stddef.h>\n");
8350764Smarkm    fprintf(c_file, "#include <com_err.h>\n");
8450764Smarkm    fprintf(c_file, "#include \"%s\"\n", hfn);
8550764Smarkm    fprintf(c_file, "\n");
86233294Sstas    fprintf(c_file, "#define N_(x) (x)\n");
87233294Sstas    fprintf(c_file, "\n");
8850764Smarkm
89127807Snectar    fprintf(c_file, "static const char *%s_error_strings[] = {\n", name);
9050764Smarkm
9150764Smarkm    for(ec = codes, n = 0; ec; ec = ec->next, n++) {
9250764Smarkm	while(n < ec->number) {
9350764Smarkm	    fprintf(c_file, "\t/* %03d */ \"Reserved %s error (%d)\",\n",
9450764Smarkm		    n, name, n);
9550764Smarkm	    n++;
96233294Sstas
9750764Smarkm	}
98233294Sstas	fprintf(c_file, "\t/* %03d */ N_(\"%s\"),\n",
99233294Sstas		ec->number, ec->string);
10050764Smarkm    }
10150764Smarkm
10250764Smarkm    fprintf(c_file, "\tNULL\n");
10350764Smarkm    fprintf(c_file, "};\n");
10450764Smarkm    fprintf(c_file, "\n");
105127807Snectar    fprintf(c_file, "#define num_errors %d\n", number);
106127807Snectar    fprintf(c_file, "\n");
107233294Sstas    fprintf(c_file,
108233294Sstas	    "void initialize_%s_error_table_r(struct et_list **list)\n",
10950764Smarkm	    name);
11050764Smarkm    fprintf(c_file, "{\n");
111233294Sstas    fprintf(c_file,
112127807Snectar	    "    initialize_error_table_r(list, %s_error_strings, "
113127807Snectar	    "num_errors, ERROR_TABLE_BASE_%s);\n", name, name);
11450764Smarkm    fprintf(c_file, "}\n");
11550764Smarkm    fprintf(c_file, "\n");
11650764Smarkm    fprintf(c_file, "void initialize_%s_error_table(void)\n", name);
11750764Smarkm    fprintf(c_file, "{\n");
11850764Smarkm    fprintf(c_file,
119127807Snectar	    "    init_error_table(%s_error_strings, ERROR_TABLE_BASE_%s, "
120127807Snectar	    "num_errors);\n", name, name);
12150764Smarkm    fprintf(c_file, "}\n");
12250764Smarkm
12350764Smarkm    fclose(c_file);
12450764Smarkm    return 0;
12550764Smarkm}
12650764Smarkm
12750764Smarkmstatic int
12850764Smarkmgenerate_h(void)
12950764Smarkm{
13050764Smarkm    struct error_code *ec;
13150764Smarkm    char fn[128];
13250764Smarkm    FILE *h_file = fopen(hfn, "w");
13350764Smarkm    char *p;
13450764Smarkm
13550764Smarkm    if(h_file == NULL)
13650764Smarkm	return 1;
13750764Smarkm
13850764Smarkm    snprintf(fn, sizeof(fn), "__%s__", hfn);
13950764Smarkm    for(p = fn; *p; p++)
14050764Smarkm	if(!isalnum((unsigned char)*p))
14150764Smarkm	    *p = '_';
142233294Sstas
14350764Smarkm    fprintf(h_file, "/* Generated from %s */\n", filename);
144233294Sstas    if(id_str)
14550764Smarkm	fprintf(h_file, "/* %s */\n", id_str);
14650764Smarkm    fprintf(h_file, "\n");
14750764Smarkm    fprintf(h_file, "#ifndef %s\n", fn);
14850764Smarkm    fprintf(h_file, "#define %s\n", fn);
14950764Smarkm    fprintf(h_file, "\n");
150127807Snectar    fprintf(h_file, "struct et_list;\n");
15150764Smarkm    fprintf(h_file, "\n");
152233294Sstas    fprintf(h_file,
15350764Smarkm	    "void initialize_%s_error_table_r(struct et_list **);\n",
15450764Smarkm	    name);
15550764Smarkm    fprintf(h_file, "\n");
15650764Smarkm    fprintf(h_file, "void initialize_%s_error_table(void);\n", name);
157233294Sstas    fprintf(h_file, "#define init_%s_err_tbl initialize_%s_error_table\n",
15850764Smarkm	    name, name);
15950764Smarkm    fprintf(h_file, "\n");
16050764Smarkm    fprintf(h_file, "typedef enum %s_error_number{\n", name);
16150764Smarkm
16250764Smarkm    for(ec = codes; ec; ec = ec->next) {
163233294Sstas	fprintf(h_file, "\t%s = %ld%s\n", ec->name, base_id + ec->number,
164127807Snectar		(ec->next != NULL) ? "," : "");
16550764Smarkm    }
16650764Smarkm
16750764Smarkm    fprintf(h_file, "} %s_error_number;\n", name);
16850764Smarkm    fprintf(h_file, "\n");
169178846Sdfr    fprintf(h_file, "#define ERROR_TABLE_BASE_%s %ld\n", name, base_id);
170127807Snectar    fprintf(h_file, "\n");
171233294Sstas    fprintf(h_file, "#define COM_ERR_BINDDOMAIN_%s \"heim_com_err%ld\"\n", name, base_id);
172233294Sstas    fprintf(h_file, "\n");
17350764Smarkm    fprintf(h_file, "#endif /* %s */\n", fn);
17450764Smarkm
17550764Smarkm
17650764Smarkm    fclose(h_file);
17750764Smarkm    return 0;
17850764Smarkm}
17950764Smarkm
18050764Smarkmstatic int
18150764Smarkmgenerate(void)
18250764Smarkm{
18350764Smarkm    return generate_c() || generate_h();
18450764Smarkm}
18550764Smarkm
186233294Sstasint version_flag;
18750764Smarkmint help_flag;
18850764Smarkmstruct getargs args[] = {
189233294Sstas    { "version", 0, arg_flag, &version_flag },
19050764Smarkm    { "help", 0, arg_flag, &help_flag }
19150764Smarkm};
19250764Smarkmint num_args = sizeof(args) / sizeof(args[0]);
19350764Smarkm
19450764Smarkmstatic void
19550764Smarkmusage(int code)
19650764Smarkm{
19750764Smarkm    arg_printusage(args, num_args, NULL, "error-table");
19850764Smarkm    exit(code);
19950764Smarkm}
20050764Smarkm
20150764Smarkmint
20250764Smarkmmain(int argc, char **argv)
20350764Smarkm{
20450764Smarkm    char *p;
205178846Sdfr    int optidx = 0;
20650764Smarkm
207127807Snectar    setprogname(argv[0]);
208178846Sdfr    if(getarg(args, num_args, argc, argv, &optidx))
20950764Smarkm	usage(1);
21050764Smarkm    if(help_flag)
21150764Smarkm	usage(0);
212233294Sstas    if(version_flag) {
213233294Sstas	print_version(NULL);
214233294Sstas	exit(0);
215233294Sstas    }
21650764Smarkm
217233294Sstas    if(optidx == argc)
21850764Smarkm	usage(1);
219178846Sdfr    filename = argv[optidx];
22050764Smarkm    yyin = fopen(filename, "r");
22150764Smarkm    if(yyin == NULL)
22250764Smarkm	err(1, "%s", filename);
223233294Sstas
224233294Sstas
225233294Sstas    p = strrchr(filename, rk_PATH_DELIM);
22650764Smarkm    if(p)
22750764Smarkm	p++;
22850764Smarkm    else
22950764Smarkm	p = filename;
230178846Sdfr    strlcpy(Basename, p, sizeof(Basename));
231233294Sstas
23250764Smarkm    Basename[strcspn(Basename, ".")] = '\0';
233233294Sstas
23450764Smarkm    snprintf(hfn, sizeof(hfn), "%s.h", Basename);
23550764Smarkm    snprintf(cfn, sizeof(cfn), "%s.c", Basename);
236233294Sstas
23750764Smarkm    yyparse();
23850764Smarkm    if(numerror)
23950764Smarkm	return 1;
24050764Smarkm
24150764Smarkm    return generate();
24250764Smarkm}
243