/ lib / com_err / compile_et.c
compile_et.c
  1  /*
  2   * Copyright (c) 1998-2002 Kungliga Tekniska Högskolan
  3   * (Royal Institute of Technology, Stockholm, Sweden).
  4   * All rights reserved.
  5   *
  6   * Redistribution and use in source and binary forms, with or without
  7   * modification, are permitted provided that the following conditions
  8   * are met:
  9   *
 10   * 1. Redistributions of source code must retain the above copyright
 11   *    notice, this list of conditions and the following disclaimer.
 12   *
 13   * 2. Redistributions in binary form must reproduce the above copyright
 14   *    notice, this list of conditions and the following disclaimer in the
 15   *    documentation and/or other materials provided with the distribution.
 16   *
 17   * 3. Neither the name of the Institute nor the names of its contributors
 18   *    may be used to endorse or promote products derived from this software
 19   *    without specific prior written permission.
 20   *
 21   * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 24   * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 25   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 27   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 28   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 29   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 30   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 31   * SUCH DAMAGE.
 32   */
 33  
 34  #undef ROKEN_RENAME
 35  
 36  #include "config.h"
 37  
 38  #include "compile_et.h"
 39  #include <getarg.h>
 40  
 41  #include <roken.h>
 42  #include <err.h>
 43  #include "parse.h"
 44  
 45  int numerror;
 46  extern FILE *yyin;
 47  
 48  extern void yyparse(void);
 49  
 50  long base_id;
 51  int number;
 52  char *prefix;
 53  char *id_str;
 54  
 55  char name[128];
 56  char Basename[128];
 57  
 58  #ifdef YYDEBUG
 59  extern int yydebug = 1;
 60  #endif
 61  
 62  char *filename;
 63  char hfn[128];
 64  char cfn[128];
 65  
 66  struct error_code *codes = NULL;
 67  
 68  static int
 69  generate_c(void)
 70  {
 71      unsigned int n;
 72      struct error_code *ec;
 73  
 74      FILE *c_file = fopen(cfn, "w");
 75      if(c_file == NULL)
 76  	return 1;
 77  
 78      fprintf(c_file, "/* Generated from %s */\n", filename);
 79      if(id_str)
 80  	fprintf(c_file, "/* %s */\n", id_str);
 81      fprintf(c_file, "\n");
 82      fprintf(c_file, "#include <stddef.h>\n");
 83      fprintf(c_file, "#include <com_err.h>\n");
 84      fprintf(c_file, "#include \"%s\"\n", hfn);
 85      fprintf(c_file, "\n");
 86      fprintf(c_file, "#define N_(x) (x)\n");
 87      fprintf(c_file, "\n");
 88  
 89      fprintf(c_file, "static const char *%s_error_strings[] = {\n", name);
 90  
 91      for(ec = codes, n = 0; ec; ec = ec->next, n++) {
 92  	while(n < ec->number) {
 93  	    fprintf(c_file, "\t/* %03d */ NULL,\n", n);
 94  	    n++;
 95  
 96  	}
 97  	fprintf(c_file, "\t/* %03d */ N_(\"%s\"),\n",
 98  		ec->number, ec->string);
 99      }
100  
101      fprintf(c_file, "\tNULL\n");
102      fprintf(c_file, "};\n");
103      fprintf(c_file, "\n");
104      fprintf(c_file, "#define num_errors %d\n", number);
105      fprintf(c_file, "\n");
106      fprintf(c_file,
107  	    "void initialize_%s_error_table_r(struct et_list **list)\n",
108  	    name);
109      fprintf(c_file, "{\n");
110      fprintf(c_file,
111  	    "    initialize_error_table_r(list, %s_error_strings, "
112  	    "num_errors, ERROR_TABLE_BASE_%s);\n", name, name);
113      fprintf(c_file, "}\n");
114      fprintf(c_file, "\n");
115      fprintf(c_file, "void initialize_%s_error_table(void)\n", name);
116      fprintf(c_file, "{\n");
117      fprintf(c_file,
118  	    "    init_error_table(%s_error_strings, ERROR_TABLE_BASE_%s, "
119  	    "num_errors);\n", name, name);
120      fprintf(c_file, "}\n");
121  
122      fclose(c_file);
123      return 0;
124  }
125  
126  static int
127  generate_h(void)
128  {
129      struct error_code *ec;
130      char fn[128];
131      FILE *h_file = fopen(hfn, "w");
132      char *p;
133  
134      if(h_file == NULL)
135  	return 1;
136  
137      snprintf(fn, sizeof(fn), "__%s__", hfn);
138      for(p = fn; *p; p++)
139  	if(!isalnum((unsigned char)*p))
140  	    *p = '_';
141  
142      fprintf(h_file, "/* Generated from %s */\n", filename);
143      if(id_str)
144  	fprintf(h_file, "/* %s */\n", id_str);
145      fprintf(h_file, "\n");
146      fprintf(h_file, "#ifndef %s\n", fn);
147      fprintf(h_file, "#define %s\n", fn);
148      fprintf(h_file, "\n");
149      fprintf(h_file, "struct et_list;\n");
150      fprintf(h_file, "\n");
151      fprintf(h_file,
152  	    "void initialize_%s_error_table_r(struct et_list **);\n",
153  	    name);
154      fprintf(h_file, "\n");
155      fprintf(h_file, "void initialize_%s_error_table(void);\n", name);
156      fprintf(h_file, "#define init_%s_err_tbl initialize_%s_error_table\n",
157  	    name, name);
158      fprintf(h_file, "\n");
159      fprintf(h_file, "typedef enum %s_error_number{\n", name);
160  
161      for(ec = codes; ec; ec = ec->next) {
162  	fprintf(h_file, "\t%s = %ld%s\n", ec->name, base_id + ec->number,
163  		(ec->next != NULL) ? "," : "");
164      }
165  
166      fprintf(h_file, "} %s_error_number;\n", name);
167      fprintf(h_file, "\n");
168      fprintf(h_file, "#define ERROR_TABLE_BASE_%s %ld\n", name, base_id);
169      fprintf(h_file, "\n");
170      fprintf(h_file, "#define COM_ERR_BINDDOMAIN_%s \"heim_com_err%ld\"\n", name, base_id);
171      fprintf(h_file, "\n");
172      fprintf(h_file, "#endif /* %s */\n", fn);
173  
174  
175      fclose(h_file);
176      return 0;
177  }
178  
179  static int
180  generate(void)
181  {
182      return generate_c() || generate_h();
183  }
184  
185  int version_flag;
186  int help_flag;
187  struct getargs args[] = {
188      { "version", 0, arg_flag, &version_flag },
189      { "help", 0, arg_flag, &help_flag }
190  };
191  int num_args = sizeof(args) / sizeof(args[0]);
192  
193  static void
194  usage(int code)
195  {
196      arg_printusage(args, num_args, NULL, "error-table");
197      exit(code);
198  }
199  
200  int
201  main(int argc, char **argv)
202  {
203      char *p;
204      int optidx = 0;
205  
206      setprogname(argv[0]);
207      if(getarg(args, num_args, argc, argv, &optidx))
208  	usage(1);
209      if(help_flag)
210  	usage(0);
211      if(version_flag) {
212  	print_version(NULL);
213  	exit(0);
214      }
215  
216      if(optidx == argc)
217  	usage(1);
218      filename = argv[optidx];
219      yyin = fopen(filename, "r");
220      if(yyin == NULL)
221  	err(1, "%s", filename);
222  
223  
224      p = strrchr(filename, rk_PATH_DELIM);
225      if(p)
226  	p++;
227      else
228  	p = filename;
229      strlcpy(Basename, p, sizeof(Basename));
230  
231      Basename[strcspn(Basename, ".")] = '\0';
232  
233      snprintf(hfn, sizeof(hfn), "%s.h", Basename);
234      snprintf(cfn, sizeof(cfn), "%s.c", Basename);
235  
236      yyparse();
237      if(numerror)
238  	return 1;
239  
240      return generate();
241  }