/crypto/heimdal/lib/com_err/compile_et.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 242 lines · 171 code · 39 blank · 32 comment · 22 complexity · bc14faeea9fcd08ced93f16c15483804 MD5 · raw file

  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. #undef ROKEN_RENAME
  34. #include "config.h"
  35. #include "compile_et.h"
  36. #include <getarg.h>
  37. #include <roken.h>
  38. #include <err.h>
  39. #include "parse.h"
  40. int numerror;
  41. extern FILE *yyin;
  42. extern void yyparse(void);
  43. long base_id;
  44. int number;
  45. char *prefix;
  46. char *id_str;
  47. char name[128];
  48. char Basename[128];
  49. #ifdef YYDEBUG
  50. extern int yydebug = 1;
  51. #endif
  52. char *filename;
  53. char hfn[128];
  54. char cfn[128];
  55. struct error_code *codes = NULL;
  56. static int
  57. generate_c(void)
  58. {
  59. int n;
  60. struct error_code *ec;
  61. FILE *c_file = fopen(cfn, "w");
  62. if(c_file == NULL)
  63. return 1;
  64. fprintf(c_file, "/* Generated from %s */\n", filename);
  65. if(id_str)
  66. fprintf(c_file, "/* %s */\n", id_str);
  67. fprintf(c_file, "\n");
  68. fprintf(c_file, "#include <stddef.h>\n");
  69. fprintf(c_file, "#include <com_err.h>\n");
  70. fprintf(c_file, "#include \"%s\"\n", hfn);
  71. fprintf(c_file, "\n");
  72. fprintf(c_file, "#define N_(x) (x)\n");
  73. fprintf(c_file, "\n");
  74. fprintf(c_file, "static const char *%s_error_strings[] = {\n", name);
  75. for(ec = codes, n = 0; ec; ec = ec->next, n++) {
  76. while(n < ec->number) {
  77. fprintf(c_file, "\t/* %03d */ \"Reserved %s error (%d)\",\n",
  78. n, name, n);
  79. n++;
  80. }
  81. fprintf(c_file, "\t/* %03d */ N_(\"%s\"),\n",
  82. ec->number, ec->string);
  83. }
  84. fprintf(c_file, "\tNULL\n");
  85. fprintf(c_file, "};\n");
  86. fprintf(c_file, "\n");
  87. fprintf(c_file, "#define num_errors %d\n", number);
  88. fprintf(c_file, "\n");
  89. fprintf(c_file,
  90. "void initialize_%s_error_table_r(struct et_list **list)\n",
  91. name);
  92. fprintf(c_file, "{\n");
  93. fprintf(c_file,
  94. " initialize_error_table_r(list, %s_error_strings, "
  95. "num_errors, ERROR_TABLE_BASE_%s);\n", name, name);
  96. fprintf(c_file, "}\n");
  97. fprintf(c_file, "\n");
  98. fprintf(c_file, "void initialize_%s_error_table(void)\n", name);
  99. fprintf(c_file, "{\n");
  100. fprintf(c_file,
  101. " init_error_table(%s_error_strings, ERROR_TABLE_BASE_%s, "
  102. "num_errors);\n", name, name);
  103. fprintf(c_file, "}\n");
  104. fclose(c_file);
  105. return 0;
  106. }
  107. static int
  108. generate_h(void)
  109. {
  110. struct error_code *ec;
  111. char fn[128];
  112. FILE *h_file = fopen(hfn, "w");
  113. char *p;
  114. if(h_file == NULL)
  115. return 1;
  116. snprintf(fn, sizeof(fn), "__%s__", hfn);
  117. for(p = fn; *p; p++)
  118. if(!isalnum((unsigned char)*p))
  119. *p = '_';
  120. fprintf(h_file, "/* Generated from %s */\n", filename);
  121. if(id_str)
  122. fprintf(h_file, "/* %s */\n", id_str);
  123. fprintf(h_file, "\n");
  124. fprintf(h_file, "#ifndef %s\n", fn);
  125. fprintf(h_file, "#define %s\n", fn);
  126. fprintf(h_file, "\n");
  127. fprintf(h_file, "struct et_list;\n");
  128. fprintf(h_file, "\n");
  129. fprintf(h_file,
  130. "void initialize_%s_error_table_r(struct et_list **);\n",
  131. name);
  132. fprintf(h_file, "\n");
  133. fprintf(h_file, "void initialize_%s_error_table(void);\n", name);
  134. fprintf(h_file, "#define init_%s_err_tbl initialize_%s_error_table\n",
  135. name, name);
  136. fprintf(h_file, "\n");
  137. fprintf(h_file, "typedef enum %s_error_number{\n", name);
  138. for(ec = codes; ec; ec = ec->next) {
  139. fprintf(h_file, "\t%s = %ld%s\n", ec->name, base_id + ec->number,
  140. (ec->next != NULL) ? "," : "");
  141. }
  142. fprintf(h_file, "} %s_error_number;\n", name);
  143. fprintf(h_file, "\n");
  144. fprintf(h_file, "#define ERROR_TABLE_BASE_%s %ld\n", name, base_id);
  145. fprintf(h_file, "\n");
  146. fprintf(h_file, "#define COM_ERR_BINDDOMAIN_%s \"heim_com_err%ld\"\n", name, base_id);
  147. fprintf(h_file, "\n");
  148. fprintf(h_file, "#endif /* %s */\n", fn);
  149. fclose(h_file);
  150. return 0;
  151. }
  152. static int
  153. generate(void)
  154. {
  155. return generate_c() || generate_h();
  156. }
  157. int version_flag;
  158. int help_flag;
  159. struct getargs args[] = {
  160. { "version", 0, arg_flag, &version_flag },
  161. { "help", 0, arg_flag, &help_flag }
  162. };
  163. int num_args = sizeof(args) / sizeof(args[0]);
  164. static void
  165. usage(int code)
  166. {
  167. arg_printusage(args, num_args, NULL, "error-table");
  168. exit(code);
  169. }
  170. int
  171. main(int argc, char **argv)
  172. {
  173. char *p;
  174. int optidx = 0;
  175. setprogname(argv[0]);
  176. if(getarg(args, num_args, argc, argv, &optidx))
  177. usage(1);
  178. if(help_flag)
  179. usage(0);
  180. if(version_flag) {
  181. print_version(NULL);
  182. exit(0);
  183. }
  184. if(optidx == argc)
  185. usage(1);
  186. filename = argv[optidx];
  187. yyin = fopen(filename, "r");
  188. if(yyin == NULL)
  189. err(1, "%s", filename);
  190. p = strrchr(filename, rk_PATH_DELIM);
  191. if(p)
  192. p++;
  193. else
  194. p = filename;
  195. strlcpy(Basename, p, sizeof(Basename));
  196. Basename[strcspn(Basename, ".")] = '\0';
  197. snprintf(hfn, sizeof(hfn), "%s.h", Basename);
  198. snprintf(cfn, sizeof(cfn), "%s.c", Basename);
  199. yyparse();
  200. if(numerror)
  201. return 1;
  202. return generate();
  203. }