mksymtab.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /****************************************************************************
  2. * tools/mksymtab.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /****************************************************************************
  21. * Included Files
  22. ****************************************************************************/
  23. #include <stdbool.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <unistd.h>
  28. #include <errno.h>
  29. #include "csvparser.h"
  30. /****************************************************************************
  31. * Pre-processor Definitions
  32. ****************************************************************************/
  33. #define MAX_HEADER_FILES 500
  34. #define SYMTAB_NAME "g_symtab"
  35. #define NSYMBOLS_NAME "g_nsymbols"
  36. /****************************************************************************
  37. * Private Types
  38. ****************************************************************************/
  39. /****************************************************************************
  40. * Private Data
  41. ****************************************************************************/
  42. static const char *g_hdrfiles[MAX_HEADER_FILES];
  43. static int nhdrfiles;
  44. /****************************************************************************
  45. * Private Functions
  46. ****************************************************************************/
  47. static void show_usage(const char *progname)
  48. {
  49. fprintf(stderr,
  50. "USAGE:\n");
  51. fprintf(stderr,
  52. "%s [-d] <cvs-file> <symtab-file> [<symtab-name> [<nsymbols-name>]]\n\n",
  53. progname);
  54. fprintf(stderr,
  55. "Where:\n\n");
  56. fprintf(stderr,
  57. " <cvs-file> : The path to the input CSV file (required)\n");
  58. fprintf(stderr,
  59. " <symtab-file> : The path to the output symbol table file\n");
  60. fprintf(stderr,
  61. "(required)\n");
  62. fprintf(stderr,
  63. " <symtab-name> : Optional name for the symbol table variable\n");
  64. fprintf(stderr,
  65. " Default: \"%s\"\n", SYMTAB_NAME);
  66. fprintf(stderr,
  67. " <nsymbols-name> : Optional name for the symbol table variable\n");
  68. fprintf(stderr,
  69. " Default: \"%s\"\n", NSYMBOLS_NAME);
  70. fprintf(stderr,
  71. " -d : Enable debug output\n");
  72. exit(EXIT_FAILURE);
  73. }
  74. static bool check_hdrfile(const char *hdrfile)
  75. {
  76. int i;
  77. for (i = 0; i < nhdrfiles; i++)
  78. {
  79. if (strcmp(g_hdrfiles[i], hdrfile) == 0)
  80. {
  81. return true;
  82. }
  83. }
  84. return false;
  85. }
  86. static void add_hdrfile(const char *hdrfile)
  87. {
  88. if (hdrfile && strlen(hdrfile) > 0)
  89. {
  90. if (!check_hdrfile(hdrfile))
  91. {
  92. if (nhdrfiles > MAX_HEADER_FILES)
  93. {
  94. fprintf(stderr,
  95. "ERROR: Too man header files. Increase MAX_HEADER_FILES\n");
  96. exit(EXIT_FAILURE);
  97. }
  98. g_hdrfiles[nhdrfiles] = strdup(hdrfile);
  99. nhdrfiles++;
  100. }
  101. }
  102. }
  103. /****************************************************************************
  104. * Public Functions
  105. ****************************************************************************/
  106. int main(int argc, char **argv, char **envp)
  107. {
  108. char *csvpath;
  109. char *sympath;
  110. char *symtab;
  111. char *nsymbols;
  112. char *nextterm;
  113. char *finalterm;
  114. char *ptr;
  115. bool cond;
  116. FILE *instream;
  117. FILE *outstream;
  118. int ch;
  119. int i;
  120. /* Parse command line options */
  121. symtab = SYMTAB_NAME;
  122. nsymbols = NSYMBOLS_NAME;
  123. g_debug = false;
  124. while ((ch = getopt(argc, argv, ":d")) > 0)
  125. {
  126. switch (ch)
  127. {
  128. case 'd' :
  129. g_debug = true;
  130. break;
  131. case '?' :
  132. fprintf(stderr, "Unrecognized option: %c\n", optopt);
  133. show_usage(argv[0]);
  134. case ':' :
  135. fprintf(stderr, "Missing option argument, option: %c\n", optopt);
  136. show_usage(argv[0]);
  137. default:
  138. fprintf(stderr, "Unexpected option: %c\n", ch);
  139. show_usage(argv[0]);
  140. }
  141. }
  142. if (optind >= argc)
  143. {
  144. fprintf(stderr, "Missing <cvs-file> and <symtab-file>\n");
  145. show_usage(argv[0]);
  146. }
  147. csvpath = argv[optind];
  148. optind++;
  149. if (optind >= argc)
  150. {
  151. fprintf(stderr, "Missing <symtab-file>\n");
  152. show_usage(argv[0]);
  153. }
  154. sympath = argv[optind];
  155. optind++;
  156. if (optind < argc)
  157. {
  158. symtab = argv[optind];
  159. optind++;
  160. }
  161. if (optind < argc)
  162. {
  163. nsymbols = argv[optind];
  164. optind++;
  165. }
  166. if (optind < argc)
  167. {
  168. fprintf(stderr, "Unexpected garbage at the end of the line\n");
  169. show_usage(argv[0]);
  170. }
  171. /* Open the CSV file for reading */
  172. instream = fopen(csvpath, "r");
  173. if (!instream)
  174. {
  175. fprintf(stderr, "open %s failed: %s\n", csvpath, strerror(errno));
  176. exit(EXIT_FAILURE);
  177. }
  178. /* Open the Symbol table file for writing */
  179. outstream = fopen(sympath, "w");
  180. if (!outstream)
  181. {
  182. fprintf(stderr, "open %s failed: %s\n", csvpath, strerror(errno));
  183. exit(EXIT_FAILURE);
  184. }
  185. /* Get all of the header files that we need to include */
  186. while ((ptr = read_line(instream)) != NULL)
  187. {
  188. /* Parse the line from the CVS file */
  189. int nargs = parse_csvline(ptr);
  190. if (nargs < PARM1_INDEX)
  191. {
  192. fprintf(stderr, "Only %d arguments found: %s\n", nargs, g_line);
  193. exit(EXIT_FAILURE);
  194. }
  195. /* Add the header file to the list of header files we need to include */
  196. add_hdrfile(g_parm[HEADER_INDEX]);
  197. }
  198. /* Back to the beginning */
  199. rewind(instream);
  200. /* Output up-front file boilerplate */
  201. fprintf(outstream,
  202. "/* %s: Auto-generated symbol table. Do not edit */\n\n", sympath);
  203. fprintf(outstream, "#include <nuttx/config.h>\n");
  204. fprintf(outstream, "#include <nuttx/compiler.h>\n");
  205. fprintf(outstream, "#include <nuttx/symtab.h>\n\n");
  206. /* Output all of the require header files */
  207. for (i = 0; i < nhdrfiles; i++)
  208. {
  209. fprintf(outstream, "#include <%s>\n", g_hdrfiles[i]);
  210. }
  211. /* Now the symbol table itself */
  212. fprintf(outstream, "\nconst struct symtab_s %s[] =\n", symtab);
  213. fprintf(outstream, "{\n");
  214. /* Parse each line in the CVS file */
  215. nextterm = "";
  216. finalterm = "";
  217. while ((ptr = read_line(instream)) != NULL)
  218. {
  219. /* Parse the line from the CVS file */
  220. int nargs = parse_csvline(ptr);
  221. if (nargs < PARM1_INDEX)
  222. {
  223. fprintf(stderr, "Only %d arguments found: %s\n", nargs, g_line);
  224. exit(EXIT_FAILURE);
  225. }
  226. /* Output any conditional compilation */
  227. cond = (g_parm[COND_INDEX] && strlen(g_parm[COND_INDEX]) > 0);
  228. if (cond)
  229. {
  230. fprintf(outstream, "%s#if %s\n", nextterm, g_parm[COND_INDEX]);
  231. nextterm = "";
  232. }
  233. /* Output the symbol table entry */
  234. fprintf(outstream, "%s { \"%s\", (FAR const void *)%s }",
  235. nextterm, g_parm[NAME_INDEX], g_parm[NAME_INDEX]);
  236. if (cond)
  237. {
  238. nextterm = ",\n#endif\n";
  239. finalterm = "\n#endif\n";
  240. }
  241. else
  242. {
  243. nextterm = ",\n";
  244. finalterm = "\n";
  245. }
  246. }
  247. fprintf(outstream, "%s};\n\n", finalterm);
  248. fprintf(outstream,
  249. "#define NSYMBOLS (sizeof(%s) / sizeof (struct symtab_s))\n", symtab);
  250. fprintf(outstream, "int %s = NSYMBOLS;\n", nsymbols);
  251. /* Close the CSV and symbol table files and exit */
  252. fclose(instream);
  253. fclose(outstream);
  254. return EXIT_SUCCESS;
  255. }