preprocess.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
  4. #include <ctype.h>
  5. #include <stdarg.h>
  6. #include <stdbool.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <array_size.h>
  11. #include <list.h>
  12. #include <xalloc.h>
  13. #include "internal.h"
  14. #include "lkc.h"
  15. #include "preprocess.h"
  16. static char *expand_string_with_args(const char *in, int argc, char *argv[]);
  17. static char *expand_string(const char *in);
  18. static void __attribute__((noreturn)) pperror(const char *format, ...)
  19. {
  20. va_list ap;
  21. fprintf(stderr, "%s:%d: ", cur_filename, yylineno);
  22. va_start(ap, format);
  23. vfprintf(stderr, format, ap);
  24. va_end(ap);
  25. fprintf(stderr, "\n");
  26. exit(1);
  27. }
  28. /*
  29. * Environment variables
  30. */
  31. static LIST_HEAD(env_list);
  32. struct env {
  33. char *name;
  34. char *value;
  35. struct list_head node;
  36. };
  37. static void env_add(const char *name, const char *value)
  38. {
  39. struct env *e;
  40. e = xmalloc(sizeof(*e));
  41. e->name = xstrdup(name);
  42. e->value = xstrdup(value);
  43. list_add_tail(&e->node, &env_list);
  44. }
  45. static void env_del(struct env *e)
  46. {
  47. list_del(&e->node);
  48. free(e->name);
  49. free(e->value);
  50. free(e);
  51. }
  52. /* The returned pointer must be freed when done */
  53. static char *env_expand(const char *name)
  54. {
  55. struct env *e;
  56. const char *value;
  57. if (!*name)
  58. return NULL;
  59. list_for_each_entry(e, &env_list, node) {
  60. if (!strcmp(name, e->name))
  61. return xstrdup(e->value);
  62. }
  63. value = getenv(name);
  64. if (!value)
  65. return NULL;
  66. /*
  67. * We need to remember all referenced environment variables.
  68. * They will be written out to include/config/auto.conf.cmd
  69. */
  70. env_add(name, value);
  71. return xstrdup(value);
  72. }
  73. void env_write_dep(struct gstr *s)
  74. {
  75. struct env *e, *tmp;
  76. list_for_each_entry_safe(e, tmp, &env_list, node) {
  77. str_printf(s,
  78. "\n"
  79. "ifneq \"$(%s)\" \"%s\"\n"
  80. "$(autoconfig): FORCE\n"
  81. "endif\n",
  82. e->name, e->value);
  83. env_del(e);
  84. }
  85. }
  86. /*
  87. * Built-in functions
  88. */
  89. struct function {
  90. const char *name;
  91. unsigned int min_args;
  92. unsigned int max_args;
  93. char *(*func)(int argc, char *argv[]);
  94. };
  95. static char *do_error_if(int argc, char *argv[])
  96. {
  97. if (!strcmp(argv[0], "y"))
  98. pperror("%s", argv[1]);
  99. return xstrdup("");
  100. }
  101. static char *do_filename(int argc, char *argv[])
  102. {
  103. return xstrdup(cur_filename);
  104. }
  105. static char *do_info(int argc, char *argv[])
  106. {
  107. printf("%s\n", argv[0]);
  108. return xstrdup("");
  109. }
  110. static char *do_lineno(int argc, char *argv[])
  111. {
  112. char buf[16];
  113. sprintf(buf, "%d", yylineno);
  114. return xstrdup(buf);
  115. }
  116. static char *do_shell(int argc, char *argv[])
  117. {
  118. FILE *p;
  119. char buf[4096];
  120. char *cmd;
  121. size_t nread;
  122. int i;
  123. cmd = argv[0];
  124. p = popen(cmd, "r");
  125. if (!p) {
  126. perror(cmd);
  127. exit(1);
  128. }
  129. nread = fread(buf, 1, sizeof(buf), p);
  130. if (nread == sizeof(buf))
  131. nread--;
  132. /* remove trailing new lines */
  133. while (nread > 0 && buf[nread - 1] == '\n')
  134. nread--;
  135. buf[nread] = 0;
  136. /* replace a new line with a space */
  137. for (i = 0; i < nread; i++) {
  138. if (buf[i] == '\n')
  139. buf[i] = ' ';
  140. }
  141. if (pclose(p) == -1) {
  142. perror(cmd);
  143. exit(1);
  144. }
  145. return xstrdup(buf);
  146. }
  147. static char *do_warning_if(int argc, char *argv[])
  148. {
  149. if (!strcmp(argv[0], "y"))
  150. fprintf(stderr, "%s:%d: %s\n", cur_filename, yylineno, argv[1]);
  151. return xstrdup("");
  152. }
  153. static const struct function function_table[] = {
  154. /* Name MIN MAX Function */
  155. { "error-if", 2, 2, do_error_if },
  156. { "filename", 0, 0, do_filename },
  157. { "info", 1, 1, do_info },
  158. { "lineno", 0, 0, do_lineno },
  159. { "shell", 1, 1, do_shell },
  160. { "warning-if", 2, 2, do_warning_if },
  161. };
  162. #define FUNCTION_MAX_ARGS 16
  163. static char *function_expand(const char *name, int argc, char *argv[])
  164. {
  165. const struct function *f;
  166. int i;
  167. for (i = 0; i < ARRAY_SIZE(function_table); i++) {
  168. f = &function_table[i];
  169. if (strcmp(f->name, name))
  170. continue;
  171. if (argc < f->min_args)
  172. pperror("too few function arguments passed to '%s'",
  173. name);
  174. if (argc > f->max_args)
  175. pperror("too many function arguments passed to '%s'",
  176. name);
  177. return f->func(argc, argv);
  178. }
  179. return NULL;
  180. }
  181. /*
  182. * Variables (and user-defined functions)
  183. */
  184. static LIST_HEAD(variable_list);
  185. struct variable {
  186. char *name;
  187. char *value;
  188. enum variable_flavor flavor;
  189. int exp_count;
  190. struct list_head node;
  191. };
  192. static struct variable *variable_lookup(const char *name)
  193. {
  194. struct variable *v;
  195. list_for_each_entry(v, &variable_list, node) {
  196. if (!strcmp(name, v->name))
  197. return v;
  198. }
  199. return NULL;
  200. }
  201. static char *variable_expand(const char *name, int argc, char *argv[])
  202. {
  203. struct variable *v;
  204. char *res;
  205. v = variable_lookup(name);
  206. if (!v)
  207. return NULL;
  208. if (argc == 0 && v->exp_count)
  209. pperror("Recursive variable '%s' references itself (eventually)",
  210. name);
  211. if (v->exp_count > 1000)
  212. pperror("Too deep recursive expansion");
  213. v->exp_count++;
  214. if (v->flavor == VAR_RECURSIVE)
  215. res = expand_string_with_args(v->value, argc, argv);
  216. else
  217. res = xstrdup(v->value);
  218. v->exp_count--;
  219. return res;
  220. }
  221. void variable_add(const char *name, const char *value,
  222. enum variable_flavor flavor)
  223. {
  224. struct variable *v;
  225. char *new_value;
  226. bool append = false;
  227. v = variable_lookup(name);
  228. if (v) {
  229. /* For defined variables, += inherits the existing flavor */
  230. if (flavor == VAR_APPEND) {
  231. flavor = v->flavor;
  232. append = true;
  233. } else {
  234. free(v->value);
  235. }
  236. } else {
  237. /* For undefined variables, += assumes the recursive flavor */
  238. if (flavor == VAR_APPEND)
  239. flavor = VAR_RECURSIVE;
  240. v = xmalloc(sizeof(*v));
  241. v->name = xstrdup(name);
  242. v->exp_count = 0;
  243. list_add_tail(&v->node, &variable_list);
  244. }
  245. v->flavor = flavor;
  246. if (flavor == VAR_SIMPLE)
  247. new_value = expand_string(value);
  248. else
  249. new_value = xstrdup(value);
  250. if (append) {
  251. v->value = xrealloc(v->value,
  252. strlen(v->value) + strlen(new_value) + 2);
  253. strcat(v->value, " ");
  254. strcat(v->value, new_value);
  255. free(new_value);
  256. } else {
  257. v->value = new_value;
  258. }
  259. }
  260. static void variable_del(struct variable *v)
  261. {
  262. list_del(&v->node);
  263. free(v->name);
  264. free(v->value);
  265. free(v);
  266. }
  267. void variable_all_del(void)
  268. {
  269. struct variable *v, *tmp;
  270. list_for_each_entry_safe(v, tmp, &variable_list, node)
  271. variable_del(v);
  272. }
  273. /*
  274. * Evaluate a clause with arguments. argc/argv are arguments from the upper
  275. * function call.
  276. *
  277. * Returned string must be freed when done
  278. */
  279. static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
  280. {
  281. char *tmp, *name, *res, *endptr, *prev, *p;
  282. int new_argc = 0;
  283. char *new_argv[FUNCTION_MAX_ARGS];
  284. int nest = 0;
  285. int i;
  286. unsigned long n;
  287. tmp = xstrndup(str, len);
  288. /*
  289. * If variable name is '1', '2', etc. It is generally an argument
  290. * from a user-function call (i.e. local-scope variable). If not
  291. * available, then look-up global-scope variables.
  292. */
  293. n = strtoul(tmp, &endptr, 10);
  294. if (!*endptr && n > 0 && n <= argc) {
  295. res = xstrdup(argv[n - 1]);
  296. goto free_tmp;
  297. }
  298. prev = p = tmp;
  299. /*
  300. * Split into tokens
  301. * The function name and arguments are separated by a comma.
  302. * For example, if the function call is like this:
  303. * $(foo,$(x),$(y))
  304. *
  305. * The input string for this helper should be:
  306. * foo,$(x),$(y)
  307. *
  308. * and split into:
  309. * new_argv[0] = 'foo'
  310. * new_argv[1] = '$(x)'
  311. * new_argv[2] = '$(y)'
  312. */
  313. while (*p) {
  314. if (nest == 0 && *p == ',') {
  315. *p = 0;
  316. if (new_argc >= FUNCTION_MAX_ARGS)
  317. pperror("too many function arguments");
  318. new_argv[new_argc++] = prev;
  319. prev = p + 1;
  320. } else if (*p == '(') {
  321. nest++;
  322. } else if (*p == ')') {
  323. nest--;
  324. }
  325. p++;
  326. }
  327. if (new_argc >= FUNCTION_MAX_ARGS)
  328. pperror("too many function arguments");
  329. new_argv[new_argc++] = prev;
  330. /*
  331. * Shift arguments
  332. * new_argv[0] represents a function name or a variable name. Put it
  333. * into 'name', then shift the rest of the arguments. This simplifies
  334. * 'const' handling.
  335. */
  336. name = expand_string_with_args(new_argv[0], argc, argv);
  337. new_argc--;
  338. for (i = 0; i < new_argc; i++)
  339. new_argv[i] = expand_string_with_args(new_argv[i + 1],
  340. argc, argv);
  341. /* Search for variables */
  342. res = variable_expand(name, new_argc, new_argv);
  343. if (res)
  344. goto free;
  345. /* Look for built-in functions */
  346. res = function_expand(name, new_argc, new_argv);
  347. if (res)
  348. goto free;
  349. /* Last, try environment variable */
  350. if (new_argc == 0) {
  351. res = env_expand(name);
  352. if (res)
  353. goto free;
  354. }
  355. res = xstrdup("");
  356. free:
  357. for (i = 0; i < new_argc; i++)
  358. free(new_argv[i]);
  359. free(name);
  360. free_tmp:
  361. free(tmp);
  362. return res;
  363. }
  364. /*
  365. * Expand a string that follows '$'
  366. *
  367. * For example, if the input string is
  368. * ($(FOO)$($(BAR)))$(BAZ)
  369. * this helper evaluates
  370. * $($(FOO)$($(BAR)))
  371. * and returns a new string containing the expansion (note that the string is
  372. * recursively expanded), also advancing 'str' to point to the next character
  373. * after the corresponding closing parenthesis, in this case, *str will be
  374. * $(BAR)
  375. */
  376. static char *expand_dollar_with_args(const char **str, int argc, char *argv[])
  377. {
  378. const char *p = *str;
  379. const char *q;
  380. int nest = 0;
  381. /*
  382. * In Kconfig, variable/function references always start with "$(".
  383. * Neither single-letter variables as in $A nor curly braces as in ${CC}
  384. * are supported. '$' not followed by '(' loses its special meaning.
  385. */
  386. if (*p != '(') {
  387. *str = p;
  388. return xstrdup("$");
  389. }
  390. p++;
  391. q = p;
  392. while (*q) {
  393. if (*q == '(') {
  394. nest++;
  395. } else if (*q == ')') {
  396. if (nest-- == 0)
  397. break;
  398. }
  399. q++;
  400. }
  401. if (!*q)
  402. pperror("unterminated reference to '%s': missing ')'", p);
  403. /* Advance 'str' to after the expanded initial portion of the string */
  404. *str = q + 1;
  405. return eval_clause(p, q - p, argc, argv);
  406. }
  407. char *expand_dollar(const char **str)
  408. {
  409. return expand_dollar_with_args(str, 0, NULL);
  410. }
  411. static char *__expand_string(const char **str, bool (*is_end)(char c),
  412. int argc, char *argv[])
  413. {
  414. const char *in, *p;
  415. char *expansion, *out;
  416. size_t in_len, out_len;
  417. out = xmalloc(1);
  418. *out = 0;
  419. out_len = 1;
  420. p = in = *str;
  421. while (1) {
  422. if (*p == '$') {
  423. in_len = p - in;
  424. p++;
  425. expansion = expand_dollar_with_args(&p, argc, argv);
  426. out_len += in_len + strlen(expansion);
  427. out = xrealloc(out, out_len);
  428. strncat(out, in, in_len);
  429. strcat(out, expansion);
  430. free(expansion);
  431. in = p;
  432. continue;
  433. }
  434. if (is_end(*p))
  435. break;
  436. p++;
  437. }
  438. in_len = p - in;
  439. out_len += in_len;
  440. out = xrealloc(out, out_len);
  441. strncat(out, in, in_len);
  442. /* Advance 'str' to the end character */
  443. *str = p;
  444. return out;
  445. }
  446. static bool is_end_of_str(char c)
  447. {
  448. return !c;
  449. }
  450. /*
  451. * Expand variables and functions in the given string. Undefined variables
  452. * expand to an empty string.
  453. * The returned string must be freed when done.
  454. */
  455. static char *expand_string_with_args(const char *in, int argc, char *argv[])
  456. {
  457. return __expand_string(&in, is_end_of_str, argc, argv);
  458. }
  459. static char *expand_string(const char *in)
  460. {
  461. return expand_string_with_args(in, 0, NULL);
  462. }
  463. static bool is_end_of_token(char c)
  464. {
  465. return !(isalnum(c) || c == '_' || c == '-');
  466. }
  467. /*
  468. * Expand variables in a token. The parsing stops when a token separater
  469. * (in most cases, it is a whitespace) is encountered. 'str' is updated to
  470. * point to the next character.
  471. *
  472. * The returned string must be freed when done.
  473. */
  474. char *expand_one_token(const char **str)
  475. {
  476. return __expand_string(str, is_end_of_token, 0, NULL);
  477. }