150764Smarkm/*
2127807Snectar * Copyright (c) 1998-2002 Kungliga Tekniska H�gskolan
350764Smarkm * (Royal Institute of Technology, Stockholm, Sweden).
450764Smarkm * All rights reserved.
550764Smarkm *
650764Smarkm * Redistribution and use in source and binary forms, with or without
750764Smarkm * modification, are permitted provided that the following conditions
850764Smarkm * are met:
950764Smarkm *
1050764Smarkm * 1. Redistributions of source code must retain the above copyright
1150764Smarkm *    notice, this list of conditions and the following disclaimer.
1250764Smarkm *
1350764Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1450764Smarkm *    notice, this list of conditions and the following disclaimer in the
1550764Smarkm *    documentation and/or other materials provided with the distribution.
1650764Smarkm *
17127807Snectar * 3. Neither the name of the Institute nor the names of its contributors
1850764Smarkm *    may be used to endorse or promote products derived from this software
1950764Smarkm *    without specific prior written permission.
2050764Smarkm *
2150764Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2250764Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2350764Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2450764Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2550764Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2650764Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2750764Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2850764Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2950764Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3050764Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3150764Smarkm * SUCH DAMAGE.
3250764Smarkm */
33127807Snectar/* $FreeBSD$ */
3450764Smarkm
3550764Smarkm#undef ROKEN_RENAME
3650764Smarkm#include "compile_et.h"
3750764Smarkm#include <getarg.h>
3850764Smarkm
3950880Smarkm#if 0
40178846SdfrRCSID("$Id: compile_et.c 15426 2005-06-16 19:21:42Z lha $");
4150880Smarkm#endif
4250764Smarkm
4350764Smarkm#include <err.h>
4450764Smarkm#include "parse.h"
4550764Smarkm
4650764Smarkmint numerror;
4750764Smarkmextern FILE *yyin;
4850764Smarkm
4950764Smarkmextern void yyparse(void);
5050764Smarkm
51178846Sdfrlong base_id;
5250764Smarkmint number;
5350764Smarkmchar *prefix;
5450764Smarkmchar *id_str;
5550764Smarkm
5650764Smarkmchar name[128];
5750764Smarkmchar Basename[128];
5850764Smarkm
5950764Smarkm#ifdef YYDEBUG
6050764Smarkmextern int yydebug = 1;
6150764Smarkm#endif
6250764Smarkm
6350764Smarkmchar *filename;
6450764Smarkmchar hfn[128];
6550764Smarkmchar cfn[128];
6650764Smarkm
6750764Smarkmstruct error_code *codes = NULL;
6850764Smarkm
6950764Smarkmstatic int
7050764Smarkmgenerate_c(void)
7150764Smarkm{
7250764Smarkm    int n;
7350764Smarkm    struct error_code *ec;
7450764Smarkm
7550764Smarkm    FILE *c_file = fopen(cfn, "w");
7650764Smarkm    if(c_file == NULL)
7750764Smarkm	return 1;
7850764Smarkm
7950764Smarkm    fprintf(c_file, "/* Generated from %s */\n", filename);
8050764Smarkm    if(id_str)
8150764Smarkm	fprintf(c_file, "/* %s */\n", id_str);
8250764Smarkm    fprintf(c_file, "\n");
8350764Smarkm    fprintf(c_file, "#include <stddef.h>\n");
8450764Smarkm    fprintf(c_file, "#include <com_err.h>\n");
8550764Smarkm    fprintf(c_file, "#include \"%s\"\n", hfn);
8650764Smarkm    fprintf(c_file, "\n");
8750764Smarkm
88127807Snectar    fprintf(c_file, "static const char *%s_error_strings[] = {\n", name);
8950764Smarkm
9050764Smarkm    for(ec = codes, n = 0; ec; ec = ec->next, n++) {
9150764Smarkm	while(n < ec->number) {
9250764Smarkm	    fprintf(c_file, "\t/* %03d */ \"Reserved %s error (%d)\",\n",
9350764Smarkm		    n, name, n);
9450764Smarkm	    n++;
9550764Smarkm
9650764Smarkm	}
9750764Smarkm	fprintf(c_file, "\t/* %03d */ \"%s\",\n", ec->number, ec->string);
9850764Smarkm    }
9950764Smarkm
10050764Smarkm    fprintf(c_file, "\tNULL\n");
10150764Smarkm    fprintf(c_file, "};\n");
10250764Smarkm    fprintf(c_file, "\n");
103127807Snectar    fprintf(c_file, "#define num_errors %d\n", number);
104127807Snectar    fprintf(c_file, "\n");
10550764Smarkm    fprintf(c_file,
10650764Smarkm	    "void initialize_%s_error_table_r(struct et_list **list)\n",
10750764Smarkm	    name);
10850764Smarkm    fprintf(c_file, "{\n");
10950764Smarkm    fprintf(c_file,
110127807Snectar	    "    initialize_error_table_r(list, %s_error_strings, "
111127807Snectar	    "num_errors, ERROR_TABLE_BASE_%s);\n", name, name);
11250764Smarkm    fprintf(c_file, "}\n");
11350764Smarkm    fprintf(c_file, "\n");
11450764Smarkm    fprintf(c_file, "void initialize_%s_error_table(void)\n", name);
11550764Smarkm    fprintf(c_file, "{\n");
11650764Smarkm    fprintf(c_file,
117127807Snectar	    "    init_error_table(%s_error_strings, ERROR_TABLE_BASE_%s, "
118127807Snectar	    "num_errors);\n", name, name);
11950764Smarkm    fprintf(c_file, "}\n");
12050764Smarkm
12150764Smarkm    fclose(c_file);
12250764Smarkm    return 0;
12350764Smarkm}
12450764Smarkm
12550764Smarkmstatic int
12650764Smarkmgenerate_h(void)
12750764Smarkm{
12850764Smarkm    struct error_code *ec;
12950764Smarkm    char fn[128];
13050764Smarkm    FILE *h_file = fopen(hfn, "w");
13150764Smarkm    char *p;
13250764Smarkm
13350764Smarkm    if(h_file == NULL)
13450764Smarkm	return 1;
13550764Smarkm
13650764Smarkm    snprintf(fn, sizeof(fn), "__%s__", hfn);
13750764Smarkm    for(p = fn; *p; p++)
13850764Smarkm	if(!isalnum((unsigned char)*p))
13950764Smarkm	    *p = '_';
14050764Smarkm
14150764Smarkm    fprintf(h_file, "/* Generated from %s */\n", filename);
14250764Smarkm    if(id_str)
14350764Smarkm	fprintf(h_file, "/* %s */\n", id_str);
14450764Smarkm    fprintf(h_file, "\n");
14550764Smarkm    fprintf(h_file, "#ifndef %s\n", fn);
14650764Smarkm    fprintf(h_file, "#define %s\n", fn);
14750764Smarkm    fprintf(h_file, "\n");
148127807Snectar    fprintf(h_file, "struct et_list;\n");
14950764Smarkm    fprintf(h_file, "\n");
15050764Smarkm    fprintf(h_file,
15150764Smarkm	    "void initialize_%s_error_table_r(struct et_list **);\n",
15250764Smarkm	    name);
15350764Smarkm    fprintf(h_file, "\n");
15450764Smarkm    fprintf(h_file, "void initialize_%s_error_table(void);\n", name);
15550764Smarkm    fprintf(h_file, "#define init_%s_err_tbl initialize_%s_error_table\n",
15650764Smarkm	    name, name);
15750764Smarkm    fprintf(h_file, "\n");
15850764Smarkm    fprintf(h_file, "typedef enum %s_error_number{\n", name);
15950764Smarkm
16050764Smarkm    for(ec = codes; ec; ec = ec->next) {
161178846Sdfr	fprintf(h_file, "\t%s = %ld%s\n", ec->name, base_id + ec->number,
162127807Snectar		(ec->next != NULL) ? "," : "");
16350764Smarkm    }
16450764Smarkm
16550764Smarkm    fprintf(h_file, "} %s_error_number;\n", name);
16650764Smarkm    fprintf(h_file, "\n");
167178846Sdfr    fprintf(h_file, "#define ERROR_TABLE_BASE_%s %ld\n", name, base_id);
168127807Snectar    fprintf(h_file, "\n");
16950764Smarkm    fprintf(h_file, "#endif /* %s */\n", fn);
17050764Smarkm
17150764Smarkm
17250764Smarkm    fclose(h_file);
17350764Smarkm    return 0;
17450764Smarkm}
17550764Smarkm
17650764Smarkmstatic int
17750764Smarkmgenerate(void)
17850764Smarkm{
17950764Smarkm    return generate_c() || generate_h();
18050764Smarkm}
18150764Smarkm
18250764Smarkmint help_flag;
18350764Smarkmstruct getargs args[] = {
18450764Smarkm    { "help", 0, arg_flag, &help_flag }
18550764Smarkm};
18650764Smarkmint num_args = sizeof(args) / sizeof(args[0]);
18750764Smarkm
18850764Smarkmstatic void
18950764Smarkmusage(int code)
19050764Smarkm{
19150764Smarkm    arg_printusage(args, num_args, NULL, "error-table");
19250764Smarkm    exit(code);
19350764Smarkm}
19450764Smarkm
19550764Smarkmint
19650764Smarkmmain(int argc, char **argv)
19750764Smarkm{
19850764Smarkm    char *p;
199178846Sdfr    int optidx = 0;
20050764Smarkm
201127807Snectar    setprogname(argv[0]);
202178846Sdfr    if(getarg(args, num_args, argc, argv, &optidx))
20350764Smarkm	usage(1);
20450764Smarkm    if(help_flag)
20550764Smarkm	usage(0);
20650764Smarkm
207178846Sdfr    if(optidx == argc)
20850764Smarkm	usage(1);
209178846Sdfr    filename = argv[optidx];
21050764Smarkm    yyin = fopen(filename, "r");
21150764Smarkm    if(yyin == NULL)
21250764Smarkm	err(1, "%s", filename);
21350764Smarkm
21450764Smarkm
21550764Smarkm    p = strrchr(filename, '/');
21650764Smarkm    if(p)
21750764Smarkm	p++;
21850764Smarkm    else
21950764Smarkm	p = filename;
220178846Sdfr    strlcpy(Basename, p, sizeof(Basename));
22150764Smarkm
22250764Smarkm    Basename[strcspn(Basename, ".")] = '\0';
22350764Smarkm
22450764Smarkm    snprintf(hfn, sizeof(hfn), "%s.h", Basename);
22550764Smarkm    snprintf(cfn, sizeof(cfn), "%s.c", Basename);
22650764Smarkm
22750764Smarkm    yyparse();
22850764Smarkm    if(numerror)
22950764Smarkm	return 1;
23050764Smarkm
23150764Smarkm    return generate();
23250764Smarkm}
233