172445Sassar/*
2233294Sstas * Copyright (c) 1998-2002 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
572445Sassar *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
972445Sassar *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1272445Sassar *
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.
1672445Sassar *
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.
2072445Sassar *
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.
3272445Sassar */
3372445Sassar
3472445Sassar#undef ROKEN_RENAME
35233294Sstas
36233294Sstas#include "config.h"
37233294Sstas
3872445Sassar#include "compile_et.h"
3972445Sassar#include <getarg.h>
4072445Sassar
4172445Sassar#include <roken.h>
4272445Sassar#include <err.h>
4372445Sassar#include "parse.h"
4472445Sassar
4572445Sassarint numerror;
4672445Sassarextern FILE *yyin;
4772445Sassar
4872445Sassarextern void yyparse(void);
4972445Sassar
50178825Sdfrlong base_id;
5172445Sassarint number;
5272445Sassarchar *prefix;
5372445Sassarchar *id_str;
5472445Sassar
5572445Sassarchar name[128];
5672445Sassarchar Basename[128];
5772445Sassar
5872445Sassar#ifdef YYDEBUG
5972445Sassarextern int yydebug = 1;
6072445Sassar#endif
6172445Sassar
6272445Sassarchar *filename;
6372445Sassarchar hfn[128];
6472445Sassarchar cfn[128];
6572445Sassar
6672445Sassarstruct error_code *codes = NULL;
6772445Sassar
6872445Sassarstatic int
6972445Sassargenerate_c(void)
7072445Sassar{
7172445Sassar    int n;
7272445Sassar    struct error_code *ec;
7372445Sassar
7472445Sassar    FILE *c_file = fopen(cfn, "w");
7572445Sassar    if(c_file == NULL)
7672445Sassar	return 1;
7772445Sassar
7872445Sassar    fprintf(c_file, "/* Generated from %s */\n", filename);
79233294Sstas    if(id_str)
8072445Sassar	fprintf(c_file, "/* %s */\n", id_str);
8172445Sassar    fprintf(c_file, "\n");
8272445Sassar    fprintf(c_file, "#include <stddef.h>\n");
8372445Sassar    fprintf(c_file, "#include <com_err.h>\n");
8472445Sassar    fprintf(c_file, "#include \"%s\"\n", hfn);
8572445Sassar    fprintf(c_file, "\n");
86233294Sstas    fprintf(c_file, "#define N_(x) (x)\n");
87233294Sstas    fprintf(c_file, "\n");
8872445Sassar
89102644Snectar    fprintf(c_file, "static const char *%s_error_strings[] = {\n", name);
9072445Sassar
9172445Sassar    for(ec = codes, n = 0; ec; ec = ec->next, n++) {
9272445Sassar	while(n < ec->number) {
9372445Sassar	    fprintf(c_file, "\t/* %03d */ \"Reserved %s error (%d)\",\n",
9472445Sassar		    n, name, n);
9572445Sassar	    n++;
96233294Sstas
9772445Sassar	}
98233294Sstas	fprintf(c_file, "\t/* %03d */ N_(\"%s\"),\n",
99233294Sstas		ec->number, ec->string);
10072445Sassar    }
10172445Sassar
10272445Sassar    fprintf(c_file, "\tNULL\n");
10372445Sassar    fprintf(c_file, "};\n");
10472445Sassar    fprintf(c_file, "\n");
105102644Snectar    fprintf(c_file, "#define num_errors %d\n", number);
106102644Snectar    fprintf(c_file, "\n");
107233294Sstas    fprintf(c_file,
108233294Sstas	    "void initialize_%s_error_table_r(struct et_list **list)\n",
10972445Sassar	    name);
11072445Sassar    fprintf(c_file, "{\n");
111233294Sstas    fprintf(c_file,
112102644Snectar	    "    initialize_error_table_r(list, %s_error_strings, "
113102644Snectar	    "num_errors, ERROR_TABLE_BASE_%s);\n", name, name);
11472445Sassar    fprintf(c_file, "}\n");
11572445Sassar    fprintf(c_file, "\n");
11672445Sassar    fprintf(c_file, "void initialize_%s_error_table(void)\n", name);
11772445Sassar    fprintf(c_file, "{\n");
11872445Sassar    fprintf(c_file,
119102644Snectar	    "    init_error_table(%s_error_strings, ERROR_TABLE_BASE_%s, "
120102644Snectar	    "num_errors);\n", name, name);
12172445Sassar    fprintf(c_file, "}\n");
12272445Sassar
12372445Sassar    fclose(c_file);
12472445Sassar    return 0;
12572445Sassar}
12672445Sassar
12772445Sassarstatic int
12872445Sassargenerate_h(void)
12972445Sassar{
13072445Sassar    struct error_code *ec;
13172445Sassar    char fn[128];
13272445Sassar    FILE *h_file = fopen(hfn, "w");
13372445Sassar    char *p;
13472445Sassar
13572445Sassar    if(h_file == NULL)
13672445Sassar	return 1;
13772445Sassar
13872445Sassar    snprintf(fn, sizeof(fn), "__%s__", hfn);
13972445Sassar    for(p = fn; *p; p++)
14072445Sassar	if(!isalnum((unsigned char)*p))
14172445Sassar	    *p = '_';
142233294Sstas
14372445Sassar    fprintf(h_file, "/* Generated from %s */\n", filename);
144233294Sstas    if(id_str)
14572445Sassar	fprintf(h_file, "/* %s */\n", id_str);
14672445Sassar    fprintf(h_file, "\n");
14772445Sassar    fprintf(h_file, "#ifndef %s\n", fn);
14872445Sassar    fprintf(h_file, "#define %s\n", fn);
14972445Sassar    fprintf(h_file, "\n");
150102644Snectar    fprintf(h_file, "struct et_list;\n");
15172445Sassar    fprintf(h_file, "\n");
152233294Sstas    fprintf(h_file,
15372445Sassar	    "void initialize_%s_error_table_r(struct et_list **);\n",
15472445Sassar	    name);
15572445Sassar    fprintf(h_file, "\n");
15672445Sassar    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",
15872445Sassar	    name, name);
15972445Sassar    fprintf(h_file, "\n");
16072445Sassar    fprintf(h_file, "typedef enum %s_error_number{\n", name);
16172445Sassar
16272445Sassar    for(ec = codes; ec; ec = ec->next) {
163233294Sstas	fprintf(h_file, "\t%s = %ld%s\n", ec->name, base_id + ec->number,
164102644Snectar		(ec->next != NULL) ? "," : "");
16572445Sassar    }
16672445Sassar
16772445Sassar    fprintf(h_file, "} %s_error_number;\n", name);
16872445Sassar    fprintf(h_file, "\n");
169178825Sdfr    fprintf(h_file, "#define ERROR_TABLE_BASE_%s %ld\n", name, base_id);
170102644Snectar    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");
17372445Sassar    fprintf(h_file, "#endif /* %s */\n", fn);
17472445Sassar
17572445Sassar
17672445Sassar    fclose(h_file);
17772445Sassar    return 0;
17872445Sassar}
17972445Sassar
18072445Sassarstatic int
18172445Sassargenerate(void)
18272445Sassar{
18372445Sassar    return generate_c() || generate_h();
18472445Sassar}
18572445Sassar
18672445Sassarint version_flag;
18772445Sassarint help_flag;
18872445Sassarstruct getargs args[] = {
18972445Sassar    { "version", 0, arg_flag, &version_flag },
19072445Sassar    { "help", 0, arg_flag, &help_flag }
19172445Sassar};
19272445Sassarint num_args = sizeof(args) / sizeof(args[0]);
19372445Sassar
19472445Sassarstatic void
19572445Sassarusage(int code)
19672445Sassar{
19772445Sassar    arg_printusage(args, num_args, NULL, "error-table");
19872445Sassar    exit(code);
19972445Sassar}
20072445Sassar
20172445Sassarint
20272445Sassarmain(int argc, char **argv)
20372445Sassar{
20472445Sassar    char *p;
205178825Sdfr    int optidx = 0;
20672445Sassar
20778527Sassar    setprogname(argv[0]);
208178825Sdfr    if(getarg(args, num_args, argc, argv, &optidx))
20972445Sassar	usage(1);
21072445Sassar    if(help_flag)
21172445Sassar	usage(0);
21272445Sassar    if(version_flag) {
21372445Sassar	print_version(NULL);
21472445Sassar	exit(0);
21572445Sassar    }
21672445Sassar
217233294Sstas    if(optidx == argc)
21872445Sassar	usage(1);
219178825Sdfr    filename = argv[optidx];
22072445Sassar    yyin = fopen(filename, "r");
22172445Sassar    if(yyin == NULL)
22272445Sassar	err(1, "%s", filename);
223233294Sstas
224233294Sstas
225233294Sstas    p = strrchr(filename, rk_PATH_DELIM);
22672445Sassar    if(p)
22772445Sassar	p++;
22872445Sassar    else
22972445Sassar	p = filename;
230178825Sdfr    strlcpy(Basename, p, sizeof(Basename));
231233294Sstas
23272445Sassar    Basename[strcspn(Basename, ".")] = '\0';
233233294Sstas
23472445Sassar    snprintf(hfn, sizeof(hfn), "%s.h", Basename);
23572445Sassar    snprintf(cfn, sizeof(cfn), "%s.c", Basename);
236233294Sstas
23772445Sassar    yyparse();
23872445Sassar    if(numerror)
23972445Sassar	return 1;
24072445Sassar
24172445Sassar    return generate();
24272445Sassar}
243