cfgdefine.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /****************************************************************************
  2. * tools/cfgdefine.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 <string.h>
  24. #include <ctype.h>
  25. #include "cfgdefine.h"
  26. /****************************************************************************
  27. * Pre-processor Definitions
  28. ****************************************************************************/
  29. /****************************************************************************
  30. * Public Data
  31. ****************************************************************************/
  32. char line[LINESIZE + 1];
  33. /****************************************************************************
  34. * Private Data
  35. ****************************************************************************/
  36. /* These are configuration variable name that are quoted by configuration
  37. * tool but which must be unquoted when used in C code.
  38. */
  39. static const char *dequote_list[] =
  40. {
  41. /* NuttX */
  42. "CONFIG_DEBUG_OPTLEVEL", /* Custom debug level */
  43. "CONFIG_EXECFUNCS_NSYMBOLS_VAR", /* Variable holding number of symbols in the table */
  44. "CONFIG_EXECFUNCS_SYMTAB_ARRAY", /* Symbol table array used by exec[l|v] */
  45. "CONFIG_INIT_ARGS", /* Argument list of entry point */
  46. "CONFIG_INIT_SYMTAB", /* Global symbol table */
  47. "CONFIG_INIT_NEXPORTS", /* Global symbol table size */
  48. "CONFIG_MODLIB_SYMTAB_ARRAY", /* Symbol table array used by modlib functions */
  49. "CONFIG_MODLIB_NSYMBOLS_VAR", /* Variable holding number of symbols in the table */
  50. "CONFIG_PASS1_BUILDIR", /* Pass1 build directory */
  51. "CONFIG_PASS1_TARGET", /* Pass1 build target */
  52. "CONFIG_PASS1_OBJECT", /* Pass1 build object */
  53. "CONFIG_USER_ENTRYPOINT", /* Name of entry point function */
  54. /* NxWidgets/NxWM */
  55. "CONFIG_NXWM_BACKGROUND_IMAGE", /* Name of bitmap image class */
  56. "CONFIG_NXWM_CALIBRATION_ICON", /* Name of bitmap image class */
  57. "CONFIG_NXWM_HEXCALCULATOR_ICON", /* Name of bitmap image class */
  58. "CONFIG_NXWM_MINIMIZE_BITMAP", /* Name of bitmap image class */
  59. "CONFIG_NXWM_NXTERM_ICON", /* Name of bitmap image class */
  60. "CONFIG_NXWM_STARTWINDOW_ICON", /* Name of bitmap image class */
  61. "CONFIG_NXWM_STOP_BITMAP", /* Name of bitmap image class */
  62. /* apps/ definitions */
  63. "CONFIG_SYSTEM_NSH_SYMTAB_ARRAYNAME", /* Symbol table array name */
  64. "CONFIG_SYSTEM_NSH_SYMTAB_COUNTNAME", /* Name of the variable holding the number of symbols */
  65. NULL /* Marks the end of the list */
  66. };
  67. /****************************************************************************
  68. * Private Functions
  69. ****************************************************************************/
  70. /* Skip over any spaces */
  71. static char *skip_space(char *ptr)
  72. {
  73. while (*ptr && isspace((int)*ptr)) ptr++;
  74. return ptr;
  75. }
  76. /* Find the end of a variable string */
  77. static char *find_name_end(char *ptr)
  78. {
  79. while (*ptr && (isalnum((int)*ptr) || *ptr == '_')) ptr++;
  80. return ptr;
  81. }
  82. /* Find the end of a value string */
  83. static char *find_value_end(char *ptr)
  84. {
  85. while (*ptr && !isspace((int)*ptr))
  86. {
  87. if (*ptr == '"')
  88. {
  89. do ptr++; while (*ptr && *ptr != '"');
  90. if (*ptr) ptr++;
  91. }
  92. else
  93. {
  94. do ptr++; while (*ptr && !isspace((int)*ptr) && *ptr != '"');
  95. }
  96. }
  97. return ptr;
  98. }
  99. /* Read the next line from the configuration file */
  100. static char *read_line(FILE *stream)
  101. {
  102. char *ptr;
  103. for (; ; )
  104. {
  105. line[LINESIZE] = '\0';
  106. if (!fgets(line, LINESIZE, stream))
  107. {
  108. return NULL;
  109. }
  110. else
  111. {
  112. ptr = skip_space(line);
  113. if (*ptr && *ptr != '#' && *ptr != '\n')
  114. {
  115. return ptr;
  116. }
  117. }
  118. }
  119. }
  120. /* Parse the line from the configuration file into a variable name
  121. * string and a value string.
  122. */
  123. static void parse_line(char *ptr, char **varname, char **varval)
  124. {
  125. /* Skip over any leading spaces */
  126. ptr = skip_space(ptr);
  127. /* The first no-space is the beginning of the variable name */
  128. *varname = skip_space(ptr);
  129. *varval = NULL;
  130. /* Parse to the end of the variable name */
  131. ptr = find_name_end(ptr);
  132. /* An equal sign is expected next, perhaps after some white space */
  133. if (*ptr && *ptr != '=')
  134. {
  135. /* Some else follows the variable name. Terminate the variable
  136. * name and skip over any spaces.
  137. */
  138. *ptr = '\0';
  139. ptr = skip_space(ptr + 1);
  140. }
  141. /* Verify that the equal sign is present */
  142. if (*ptr == '=')
  143. {
  144. /* Make sure that the variable name is terminated (this was already
  145. * done if the name was followed by white space.
  146. */
  147. *ptr = '\0';
  148. /* The variable value should follow =, perhaps separated by some
  149. * white space.
  150. */
  151. ptr = skip_space(ptr + 1);
  152. if (*ptr)
  153. {
  154. /* Yes.. a variable follows. Save the pointer to the start
  155. * of the variable string.
  156. */
  157. *varval = ptr;
  158. /* Find the end of the variable string and make sure that it
  159. * is terminated.
  160. */
  161. ptr = find_value_end(ptr);
  162. *ptr = '\0';
  163. }
  164. }
  165. }
  166. static char *dequote_value(const char *varname, char *varval)
  167. {
  168. const char **dqnam;
  169. char *dqval = varval;
  170. char *ptr;
  171. int len;
  172. int i;
  173. if (dqval)
  174. {
  175. /* Check if the variable name is in the dequoted list of strings */
  176. for (dqnam = dequote_list; *dqnam; dqnam++)
  177. {
  178. if (strcmp(*dqnam, varname) == 0)
  179. {
  180. break;
  181. }
  182. }
  183. /* Did we find the variable name in the list of configuration variables
  184. * to be dequoted?
  185. */
  186. if (*dqnam)
  187. {
  188. /* Yes... Check if there is a trailing quote */
  189. len = strlen(dqval);
  190. if (dqval[len - 1] == '"')
  191. {
  192. /* Yes... replace it with a terminator */
  193. dqval[len - 1] = '\0';
  194. len--;
  195. }
  196. /* Is there a leading quote? */
  197. if (dqval[0] == '"')
  198. {
  199. /* Yes.. skip over the leading quote */
  200. dqval++;
  201. len--;
  202. }
  203. /* A special case is a quoted list of quoted strings. In that case
  204. * we will need to remove the backspaces from the internally quoted
  205. * strings. NOTE: this will not handle nested quoted quotes.
  206. */
  207. for (ptr = dqval; *ptr; ptr++)
  208. {
  209. /* Check for a quoted quote */
  210. if (ptr[0] == '\\' && ptr[1] == '"')
  211. {
  212. /* Delete the backslash by moving the rest of the string */
  213. for (i = 0; ptr[i]; i++)
  214. {
  215. ptr[i] = ptr[i + 1];
  216. }
  217. len--;
  218. }
  219. }
  220. /* Handle the case where nothing is left after dequoting */
  221. if (len <= 0)
  222. {
  223. dqval = NULL;
  224. }
  225. }
  226. }
  227. return dqval;
  228. }
  229. /****************************************************************************
  230. * Public Functions
  231. ****************************************************************************/
  232. void generate_definitions(FILE *stream)
  233. {
  234. char *varname;
  235. char *varval;
  236. char *ptr;
  237. /* Loop until the entire file has been parsed. */
  238. do
  239. {
  240. /* Read the next line from the file */
  241. ptr = read_line(stream);
  242. if (ptr)
  243. {
  244. /* Parse the line into a variable and a value field */
  245. parse_line(ptr, &varname, &varval);
  246. /* Was a variable name found? */
  247. if (varname)
  248. {
  249. /* Yes.. dequote the value if necessary */
  250. varval = dequote_value(varname, varval);
  251. /* If no value was provided or if the special value 'n' was
  252. * provided, then undefine the configuration variable.
  253. */
  254. if (!varval || strcmp(varval, "n") == 0)
  255. {
  256. printf("#undef %s\n", varname);
  257. }
  258. /* Simply define the configuration variable to '1' if it has
  259. * the special value "y"
  260. */
  261. else if (strcmp(varval, "y") == 0)
  262. {
  263. printf("#define %s 1\n", varname);
  264. }
  265. /* Or to '2' if it has the special value 'm' */
  266. else if (strcmp(varval, "m") == 0)
  267. {
  268. printf("#define %s 2\n", varname);
  269. }
  270. /* Otherwise, use the value as provided */
  271. else
  272. {
  273. printf("#define %s %s\n", varname, varval);
  274. }
  275. }
  276. }
  277. }
  278. while (ptr);
  279. }