2
0

confdata.c 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2002 Roman Zippel <[email protected]>
  4. */
  5. #include <sys/mman.h>
  6. #include <sys/stat.h>
  7. #include <sys/types.h>
  8. #include <ctype.h>
  9. #include <errno.h>
  10. #include <fcntl.h>
  11. #include <limits.h>
  12. #include <stdarg.h>
  13. #include <stdbool.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <time.h>
  18. #include <unistd.h>
  19. #include "lkc.h"
  20. /* return true if 'path' exists, false otherwise */
  21. static bool is_present(const char *path)
  22. {
  23. struct stat st;
  24. return !stat(path, &st);
  25. }
  26. /* return true if 'path' exists and it is a directory, false otherwise */
  27. static bool is_dir(const char *path)
  28. {
  29. struct stat st;
  30. if (stat(path, &st))
  31. return false;
  32. return S_ISDIR(st.st_mode);
  33. }
  34. /* return true if the given two files are the same, false otherwise */
  35. static bool is_same(const char *file1, const char *file2)
  36. {
  37. int fd1, fd2;
  38. struct stat st1, st2;
  39. void *map1, *map2;
  40. bool ret = false;
  41. fd1 = open(file1, O_RDONLY);
  42. if (fd1 < 0)
  43. return ret;
  44. fd2 = open(file2, O_RDONLY);
  45. if (fd2 < 0)
  46. goto close1;
  47. ret = fstat(fd1, &st1);
  48. if (ret)
  49. goto close2;
  50. ret = fstat(fd2, &st2);
  51. if (ret)
  52. goto close2;
  53. if (st1.st_size != st2.st_size)
  54. goto close2;
  55. map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
  56. if (map1 == MAP_FAILED)
  57. goto close2;
  58. map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
  59. if (map2 == MAP_FAILED)
  60. goto close2;
  61. if (bcmp(map1, map2, st1.st_size))
  62. goto close2;
  63. ret = true;
  64. close2:
  65. close(fd2);
  66. close1:
  67. close(fd1);
  68. return ret;
  69. }
  70. /*
  71. * Create the parent directory of the given path.
  72. *
  73. * For example, if 'include/config/auto.conf' is given, create 'include/config'.
  74. */
  75. static int make_parent_dir(const char *path)
  76. {
  77. char tmp[PATH_MAX + 1];
  78. char *p;
  79. strncpy(tmp, path, sizeof(tmp));
  80. tmp[sizeof(tmp) - 1] = 0;
  81. /* Remove the base name. Just return if nothing is left */
  82. p = strrchr(tmp, '/');
  83. if (!p)
  84. return 0;
  85. *(p + 1) = 0;
  86. /* Just in case it is an absolute path */
  87. p = tmp;
  88. while (*p == '/')
  89. p++;
  90. while ((p = strchr(p, '/'))) {
  91. *p = 0;
  92. /* skip if the directory exists */
  93. if (!is_dir(tmp) && mkdir(tmp, 0755))
  94. return -1;
  95. *p = '/';
  96. while (*p == '/')
  97. p++;
  98. }
  99. return 0;
  100. }
  101. static char depfile_path[PATH_MAX];
  102. static size_t depfile_prefix_len;
  103. /* touch depfile for symbol 'name' */
  104. static int conf_touch_dep(const char *name)
  105. {
  106. int fd;
  107. /* check overflow: prefix + name + '\0' must fit in buffer. */
  108. if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path))
  109. return -1;
  110. strcpy(depfile_path + depfile_prefix_len, name);
  111. fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
  112. if (fd == -1)
  113. return -1;
  114. close(fd);
  115. return 0;
  116. }
  117. static void conf_warning(const char *fmt, ...)
  118. __attribute__ ((format (printf, 1, 2)));
  119. static void conf_message(const char *fmt, ...)
  120. __attribute__ ((format (printf, 1, 2)));
  121. static const char *conf_filename;
  122. static int conf_lineno, conf_warnings;
  123. static void conf_warning(const char *fmt, ...)
  124. {
  125. va_list ap;
  126. va_start(ap, fmt);
  127. fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
  128. vfprintf(stderr, fmt, ap);
  129. fprintf(stderr, "\n");
  130. va_end(ap);
  131. conf_warnings++;
  132. }
  133. static void conf_default_message_callback(const char *s)
  134. {
  135. printf("#\n# ");
  136. printf("%s", s);
  137. printf("\n#\n");
  138. }
  139. static void (*conf_message_callback)(const char *s) =
  140. conf_default_message_callback;
  141. void conf_set_message_callback(void (*fn)(const char *s))
  142. {
  143. conf_message_callback = fn;
  144. }
  145. static void conf_message(const char *fmt, ...)
  146. {
  147. va_list ap;
  148. char buf[4096];
  149. if (!conf_message_callback)
  150. return;
  151. va_start(ap, fmt);
  152. vsnprintf(buf, sizeof(buf), fmt, ap);
  153. conf_message_callback(buf);
  154. va_end(ap);
  155. }
  156. const char *conf_get_configname(void)
  157. {
  158. char *name = getenv("KCONFIG_CONFIG");
  159. return name ? name : ".config";
  160. }
  161. static const char *conf_get_autoconfig_name(void)
  162. {
  163. char *name = getenv("KCONFIG_AUTOCONFIG");
  164. return name ? name : "include/config/auto.conf";
  165. }
  166. static const char *conf_get_autoheader_name(void)
  167. {
  168. char *name = getenv("KCONFIG_AUTOHEADER");
  169. return name ? name : "include/generated/autoconf.h";
  170. }
  171. static const char *conf_get_rustccfg_name(void)
  172. {
  173. char *name = getenv("KCONFIG_RUSTCCFG");
  174. return name ? name : "include/generated/rustc_cfg";
  175. }
  176. static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
  177. {
  178. char *p2;
  179. switch (sym->type) {
  180. case S_TRISTATE:
  181. if (p[0] == 'm') {
  182. sym->def[def].tri = mod;
  183. sym->flags |= def_flags;
  184. break;
  185. }
  186. /* fall through */
  187. case S_BOOLEAN:
  188. if (p[0] == 'y') {
  189. sym->def[def].tri = yes;
  190. sym->flags |= def_flags;
  191. break;
  192. }
  193. if (p[0] == 'n') {
  194. sym->def[def].tri = no;
  195. sym->flags |= def_flags;
  196. break;
  197. }
  198. if (def != S_DEF_AUTO)
  199. conf_warning("symbol value '%s' invalid for %s",
  200. p, sym->name);
  201. return 1;
  202. case S_STRING:
  203. /* No escaping for S_DEF_AUTO (include/config/auto.conf) */
  204. if (def != S_DEF_AUTO) {
  205. if (*p++ != '"')
  206. break;
  207. for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
  208. if (*p2 == '"') {
  209. *p2 = 0;
  210. break;
  211. }
  212. memmove(p2, p2 + 1, strlen(p2));
  213. }
  214. if (!p2) {
  215. conf_warning("invalid string found");
  216. return 1;
  217. }
  218. }
  219. /* fall through */
  220. case S_INT:
  221. case S_HEX:
  222. if (sym_string_valid(sym, p)) {
  223. sym->def[def].val = xstrdup(p);
  224. sym->flags |= def_flags;
  225. } else {
  226. if (def != S_DEF_AUTO)
  227. conf_warning("symbol value '%s' invalid for %s",
  228. p, sym->name);
  229. return 1;
  230. }
  231. break;
  232. default:
  233. ;
  234. }
  235. return 0;
  236. }
  237. #define LINE_GROWTH 16
  238. static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
  239. {
  240. char *nline;
  241. size_t new_size = slen + 1;
  242. if (new_size > *n) {
  243. new_size += LINE_GROWTH - 1;
  244. new_size *= 2;
  245. nline = xrealloc(*lineptr, new_size);
  246. if (!nline)
  247. return -1;
  248. *lineptr = nline;
  249. *n = new_size;
  250. }
  251. (*lineptr)[slen] = c;
  252. return 0;
  253. }
  254. static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream)
  255. {
  256. char *line = *lineptr;
  257. size_t slen = 0;
  258. for (;;) {
  259. int c = getc(stream);
  260. switch (c) {
  261. case '\n':
  262. if (add_byte(c, &line, slen, n) < 0)
  263. goto e_out;
  264. slen++;
  265. /* fall through */
  266. case EOF:
  267. if (add_byte('\0', &line, slen, n) < 0)
  268. goto e_out;
  269. *lineptr = line;
  270. if (slen == 0)
  271. return -1;
  272. return slen;
  273. default:
  274. if (add_byte(c, &line, slen, n) < 0)
  275. goto e_out;
  276. slen++;
  277. }
  278. }
  279. e_out:
  280. line[slen-1] = '\0';
  281. *lineptr = line;
  282. return -1;
  283. }
  284. void conf_reset(int def)
  285. {
  286. struct symbol *sym;
  287. int i, def_flags;
  288. def_flags = SYMBOL_DEF << def;
  289. for_all_symbols(i, sym) {
  290. sym->flags |= SYMBOL_CHANGED;
  291. sym->flags &= ~(def_flags|SYMBOL_VALID);
  292. if (sym_is_choice(sym))
  293. sym->flags |= def_flags;
  294. switch (sym->type) {
  295. case S_INT:
  296. case S_HEX:
  297. case S_STRING:
  298. if (sym->def[def].val)
  299. free(sym->def[def].val);
  300. /* fall through */
  301. default:
  302. sym->def[def].val = NULL;
  303. sym->def[def].tri = no;
  304. }
  305. }
  306. }
  307. int conf_read_simple(const char *name, int def)
  308. {
  309. FILE *in = NULL;
  310. char *line = NULL;
  311. size_t line_asize = 0;
  312. char *p, *p2;
  313. struct symbol *sym;
  314. int def_flags;
  315. const char *warn_unknown;
  316. const char *werror;
  317. warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
  318. werror = getenv("KCONFIG_WERROR");
  319. if (name) {
  320. in = zconf_fopen(name);
  321. } else {
  322. char *env;
  323. name = conf_get_configname();
  324. in = zconf_fopen(name);
  325. if (in)
  326. goto load;
  327. conf_set_changed(true);
  328. env = getenv("KCONFIG_DEFCONFIG_LIST");
  329. if (!env)
  330. return 1;
  331. while (1) {
  332. bool is_last;
  333. while (isspace(*env))
  334. env++;
  335. if (!*env)
  336. break;
  337. p = env;
  338. while (*p && !isspace(*p))
  339. p++;
  340. is_last = (*p == '\0');
  341. *p = '\0';
  342. in = zconf_fopen(env);
  343. if (in) {
  344. conf_message("using defaults found in %s",
  345. env);
  346. goto load;
  347. }
  348. if (is_last)
  349. break;
  350. env = p + 1;
  351. }
  352. }
  353. if (!in)
  354. return 1;
  355. load:
  356. conf_filename = name;
  357. conf_lineno = 0;
  358. conf_warnings = 0;
  359. def_flags = SYMBOL_DEF << def;
  360. conf_reset(def);
  361. while (compat_getline(&line, &line_asize, in) != -1) {
  362. conf_lineno++;
  363. sym = NULL;
  364. if (line[0] == '#') {
  365. if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
  366. continue;
  367. p = strchr(line + 2 + strlen(CONFIG_), ' ');
  368. if (!p)
  369. continue;
  370. *p++ = 0;
  371. if (strncmp(p, "is not set", 10))
  372. continue;
  373. if (def == S_DEF_USER) {
  374. sym = sym_find(line + 2 + strlen(CONFIG_));
  375. if (!sym) {
  376. if (warn_unknown)
  377. conf_warning("unknown symbol: %s",
  378. line + 2 + strlen(CONFIG_));
  379. conf_set_changed(true);
  380. continue;
  381. }
  382. } else {
  383. sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
  384. if (sym->type == S_UNKNOWN)
  385. sym->type = S_BOOLEAN;
  386. }
  387. switch (sym->type) {
  388. case S_BOOLEAN:
  389. case S_TRISTATE:
  390. sym->def[def].tri = no;
  391. sym->flags |= def_flags;
  392. break;
  393. default:
  394. ;
  395. }
  396. } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
  397. p = strchr(line + strlen(CONFIG_), '=');
  398. if (!p)
  399. continue;
  400. *p++ = 0;
  401. p2 = strchr(p, '\n');
  402. if (p2) {
  403. *p2-- = 0;
  404. if (*p2 == '\r')
  405. *p2 = 0;
  406. }
  407. sym = sym_find(line + strlen(CONFIG_));
  408. if (!sym) {
  409. if (def == S_DEF_AUTO) {
  410. /*
  411. * Reading from include/config/auto.conf
  412. * If CONFIG_FOO previously existed in
  413. * auto.conf but it is missing now,
  414. * include/config/FOO must be touched.
  415. */
  416. conf_touch_dep(line + strlen(CONFIG_));
  417. } else {
  418. if (warn_unknown)
  419. conf_warning("unknown symbol: %s",
  420. line + strlen(CONFIG_));
  421. conf_set_changed(true);
  422. }
  423. continue;
  424. }
  425. if (conf_set_sym_val(sym, def, def_flags, p))
  426. continue;
  427. } else {
  428. if (line[0] != '\r' && line[0] != '\n')
  429. conf_warning("unexpected data: %.*s",
  430. (int)strcspn(line, "\r\n"), line);
  431. continue;
  432. }
  433. if (sym && sym_is_choice_value(sym)) {
  434. struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
  435. switch (sym->def[def].tri) {
  436. case no:
  437. break;
  438. case mod:
  439. if (cs->def[def].tri == yes) {
  440. conf_warning("%s creates inconsistent choice state", sym->name);
  441. cs->flags &= ~def_flags;
  442. }
  443. break;
  444. case yes:
  445. if (cs->def[def].tri != no)
  446. conf_warning("override: %s changes choice state", sym->name);
  447. cs->def[def].val = sym;
  448. break;
  449. }
  450. cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
  451. }
  452. }
  453. free(line);
  454. fclose(in);
  455. if (conf_warnings && werror)
  456. exit(1);
  457. return 0;
  458. }
  459. int conf_read(const char *name)
  460. {
  461. struct symbol *sym;
  462. int conf_unsaved = 0;
  463. int i;
  464. conf_set_changed(false);
  465. if (conf_read_simple(name, S_DEF_USER)) {
  466. sym_calc_value(modules_sym);
  467. return 1;
  468. }
  469. sym_calc_value(modules_sym);
  470. for_all_symbols(i, sym) {
  471. sym_calc_value(sym);
  472. if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE))
  473. continue;
  474. if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
  475. /* check that calculated value agrees with saved value */
  476. switch (sym->type) {
  477. case S_BOOLEAN:
  478. case S_TRISTATE:
  479. if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym))
  480. continue;
  481. break;
  482. default:
  483. if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
  484. continue;
  485. break;
  486. }
  487. } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
  488. /* no previous value and not saved */
  489. continue;
  490. conf_unsaved++;
  491. /* maybe print value in verbose mode... */
  492. }
  493. for_all_symbols(i, sym) {
  494. if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
  495. /* Reset values of generates values, so they'll appear
  496. * as new, if they should become visible, but that
  497. * doesn't quite work if the Kconfig and the saved
  498. * configuration disagree.
  499. */
  500. if (sym->visible == no && !conf_unsaved)
  501. sym->flags &= ~SYMBOL_DEF_USER;
  502. switch (sym->type) {
  503. case S_STRING:
  504. case S_INT:
  505. case S_HEX:
  506. /* Reset a string value if it's out of range */
  507. if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
  508. break;
  509. sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
  510. conf_unsaved++;
  511. break;
  512. default:
  513. break;
  514. }
  515. }
  516. }
  517. if (conf_warnings || conf_unsaved)
  518. conf_set_changed(true);
  519. return 0;
  520. }
  521. struct comment_style {
  522. const char *decoration;
  523. const char *prefix;
  524. const char *postfix;
  525. };
  526. static const struct comment_style comment_style_pound = {
  527. .decoration = "#",
  528. .prefix = "#",
  529. .postfix = "#",
  530. };
  531. static const struct comment_style comment_style_c = {
  532. .decoration = " *",
  533. .prefix = "/*",
  534. .postfix = " */",
  535. };
  536. static void conf_write_heading(FILE *fp, const struct comment_style *cs)
  537. {
  538. if (!cs)
  539. return;
  540. fprintf(fp, "%s\n", cs->prefix);
  541. fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n",
  542. cs->decoration);
  543. fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text);
  544. fprintf(fp, "%s\n", cs->postfix);
  545. }
  546. /* The returned pointer must be freed on the caller side */
  547. static char *escape_string_value(const char *in)
  548. {
  549. const char *p;
  550. char *out;
  551. size_t len;
  552. len = strlen(in) + strlen("\"\"") + 1;
  553. p = in;
  554. while (1) {
  555. p += strcspn(p, "\"\\");
  556. if (p[0] == '\0')
  557. break;
  558. len++;
  559. p++;
  560. }
  561. out = xmalloc(len);
  562. out[0] = '\0';
  563. strcat(out, "\"");
  564. p = in;
  565. while (1) {
  566. len = strcspn(p, "\"\\");
  567. strncat(out, p, len);
  568. p += len;
  569. if (p[0] == '\0')
  570. break;
  571. strcat(out, "\\");
  572. strncat(out, p++, 1);
  573. }
  574. strcat(out, "\"");
  575. return out;
  576. }
  577. enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE };
  578. static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
  579. bool escape_string)
  580. {
  581. const char *val;
  582. char *escaped = NULL;
  583. if (sym->type == S_UNKNOWN)
  584. return;
  585. val = sym_get_string_value(sym);
  586. if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) &&
  587. output_n != OUTPUT_N && *val == 'n') {
  588. if (output_n == OUTPUT_N_AS_UNSET)
  589. fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name);
  590. return;
  591. }
  592. if (sym->type == S_STRING && escape_string) {
  593. escaped = escape_string_value(val);
  594. val = escaped;
  595. }
  596. fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val);
  597. free(escaped);
  598. }
  599. static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym)
  600. {
  601. __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true);
  602. }
  603. static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym)
  604. {
  605. __print_symbol(fp, sym, OUTPUT_N_NONE, false);
  606. }
  607. void print_symbol_for_listconfig(struct symbol *sym)
  608. {
  609. __print_symbol(stdout, sym, OUTPUT_N, true);
  610. }
  611. static void print_symbol_for_c(FILE *fp, struct symbol *sym)
  612. {
  613. const char *val;
  614. const char *sym_suffix = "";
  615. const char *val_prefix = "";
  616. char *escaped = NULL;
  617. if (sym->type == S_UNKNOWN)
  618. return;
  619. val = sym_get_string_value(sym);
  620. switch (sym->type) {
  621. case S_BOOLEAN:
  622. case S_TRISTATE:
  623. switch (*val) {
  624. case 'n':
  625. return;
  626. case 'm':
  627. sym_suffix = "_MODULE";
  628. /* fall through */
  629. default:
  630. val = "1";
  631. }
  632. break;
  633. case S_HEX:
  634. if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
  635. val_prefix = "0x";
  636. break;
  637. case S_STRING:
  638. escaped = escape_string_value(val);
  639. val = escaped;
  640. default:
  641. break;
  642. }
  643. fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix,
  644. val_prefix, val);
  645. free(escaped);
  646. }
  647. static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym)
  648. {
  649. const char *val;
  650. const char *val_prefix = "";
  651. char *val_prefixed = NULL;
  652. size_t val_prefixed_len;
  653. char *escaped = NULL;
  654. if (sym->type == S_UNKNOWN)
  655. return;
  656. val = sym_get_string_value(sym);
  657. switch (sym->type) {
  658. case S_BOOLEAN:
  659. case S_TRISTATE:
  660. /*
  661. * We do not care about disabled ones, i.e. no need for
  662. * what otherwise are "comments" in other printers.
  663. */
  664. if (*val == 'n')
  665. return;
  666. /*
  667. * To have similar functionality to the C macro `IS_ENABLED()`
  668. * we provide an empty `--cfg CONFIG_X` here in both `y`
  669. * and `m` cases.
  670. *
  671. * Then, the common `fprintf()` below will also give us
  672. * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can
  673. * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`.
  674. */
  675. fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name);
  676. break;
  677. case S_HEX:
  678. if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
  679. val_prefix = "0x";
  680. break;
  681. default:
  682. break;
  683. }
  684. if (strlen(val_prefix) > 0) {
  685. val_prefixed_len = strlen(val) + strlen(val_prefix) + 1;
  686. val_prefixed = xmalloc(val_prefixed_len);
  687. snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val);
  688. val = val_prefixed;
  689. }
  690. /* All values get escaped: the `--cfg` option only takes strings */
  691. escaped = escape_string_value(val);
  692. val = escaped;
  693. fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val);
  694. free(escaped);
  695. free(val_prefixed);
  696. }
  697. /*
  698. * Write out a minimal config.
  699. * All values that has default values are skipped as this is redundant.
  700. */
  701. int conf_write_defconfig(const char *filename)
  702. {
  703. struct symbol *sym;
  704. struct menu *menu;
  705. FILE *out;
  706. out = fopen(filename, "w");
  707. if (!out)
  708. return 1;
  709. sym_clear_all_valid();
  710. /* Traverse all menus to find all relevant symbols */
  711. menu = rootmenu.list;
  712. while (menu != NULL)
  713. {
  714. sym = menu->sym;
  715. if (sym == NULL) {
  716. if (!menu_is_visible(menu))
  717. goto next_menu;
  718. } else if (!sym_is_choice(sym)) {
  719. sym_calc_value(sym);
  720. if (!(sym->flags & SYMBOL_WRITE))
  721. goto next_menu;
  722. sym->flags &= ~SYMBOL_WRITE;
  723. /* If we cannot change the symbol - skip */
  724. if (!sym_is_changeable(sym))
  725. goto next_menu;
  726. /* If symbol equals to default value - skip */
  727. if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
  728. goto next_menu;
  729. /*
  730. * If symbol is a choice value and equals to the
  731. * default for a choice - skip.
  732. * But only if value is bool and equal to "y" and
  733. * choice is not "optional".
  734. * (If choice is "optional" then all values can be "n")
  735. */
  736. if (sym_is_choice_value(sym)) {
  737. struct symbol *cs;
  738. struct symbol *ds;
  739. cs = prop_get_symbol(sym_get_choice_prop(sym));
  740. ds = sym_choice_default(cs);
  741. if (!sym_is_optional(cs) && sym == ds) {
  742. if ((sym->type == S_BOOLEAN) &&
  743. sym_get_tristate_value(sym) == yes)
  744. goto next_menu;
  745. }
  746. }
  747. print_symbol_for_dotconfig(out, sym);
  748. }
  749. next_menu:
  750. if (menu->list != NULL) {
  751. menu = menu->list;
  752. }
  753. else if (menu->next != NULL) {
  754. menu = menu->next;
  755. } else {
  756. while ((menu = menu->parent)) {
  757. if (menu->next != NULL) {
  758. menu = menu->next;
  759. break;
  760. }
  761. }
  762. }
  763. }
  764. fclose(out);
  765. return 0;
  766. }
  767. int conf_write(const char *name)
  768. {
  769. FILE *out;
  770. struct symbol *sym;
  771. struct menu *menu;
  772. const char *str;
  773. char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
  774. char *env;
  775. int i;
  776. bool need_newline = false;
  777. if (!name)
  778. name = conf_get_configname();
  779. if (!*name) {
  780. fprintf(stderr, "config name is empty\n");
  781. return -1;
  782. }
  783. if (is_dir(name)) {
  784. fprintf(stderr, "%s: Is a directory\n", name);
  785. return -1;
  786. }
  787. if (make_parent_dir(name))
  788. return -1;
  789. env = getenv("KCONFIG_OVERWRITECONFIG");
  790. if (env && *env) {
  791. *tmpname = 0;
  792. out = fopen(name, "w");
  793. } else {
  794. snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
  795. name, (int)getpid());
  796. out = fopen(tmpname, "w");
  797. }
  798. if (!out)
  799. return 1;
  800. conf_write_heading(out, &comment_style_pound);
  801. if (!conf_get_changed())
  802. sym_clear_all_valid();
  803. menu = rootmenu.list;
  804. while (menu) {
  805. sym = menu->sym;
  806. if (!sym) {
  807. if (!menu_is_visible(menu))
  808. goto next;
  809. str = menu_get_prompt(menu);
  810. fprintf(out, "\n"
  811. "#\n"
  812. "# %s\n"
  813. "#\n", str);
  814. need_newline = false;
  815. } else if (!(sym->flags & SYMBOL_CHOICE) &&
  816. !(sym->flags & SYMBOL_WRITTEN)) {
  817. sym_calc_value(sym);
  818. if (!(sym->flags & SYMBOL_WRITE))
  819. goto next;
  820. if (need_newline) {
  821. fprintf(out, "\n");
  822. need_newline = false;
  823. }
  824. sym->flags |= SYMBOL_WRITTEN;
  825. print_symbol_for_dotconfig(out, sym);
  826. }
  827. next:
  828. if (menu->list) {
  829. menu = menu->list;
  830. continue;
  831. }
  832. end_check:
  833. if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu &&
  834. menu->prompt->type == P_MENU) {
  835. fprintf(out, "# end of %s\n", menu_get_prompt(menu));
  836. need_newline = true;
  837. }
  838. if (menu->next) {
  839. menu = menu->next;
  840. } else {
  841. menu = menu->parent;
  842. if (menu)
  843. goto end_check;
  844. }
  845. }
  846. fclose(out);
  847. for_all_symbols(i, sym)
  848. sym->flags &= ~SYMBOL_WRITTEN;
  849. if (*tmpname) {
  850. if (is_same(name, tmpname)) {
  851. conf_message("No change to %s", name);
  852. unlink(tmpname);
  853. conf_set_changed(false);
  854. return 0;
  855. }
  856. snprintf(oldname, sizeof(oldname), "%s.old", name);
  857. rename(name, oldname);
  858. if (rename(tmpname, name))
  859. return 1;
  860. }
  861. conf_message("configuration written to %s", name);
  862. conf_set_changed(false);
  863. return 0;
  864. }
  865. /* write a dependency file as used by kbuild to track dependencies */
  866. static int conf_write_autoconf_cmd(const char *autoconf_name)
  867. {
  868. char name[PATH_MAX], tmp[PATH_MAX];
  869. struct file *file;
  870. FILE *out;
  871. int ret;
  872. ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name);
  873. if (ret >= sizeof(name)) /* check truncation */
  874. return -1;
  875. if (make_parent_dir(name))
  876. return -1;
  877. ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name);
  878. if (ret >= sizeof(tmp)) /* check truncation */
  879. return -1;
  880. out = fopen(tmp, "w");
  881. if (!out) {
  882. perror("fopen");
  883. return -1;
  884. }
  885. fprintf(out, "deps_config := \\\n");
  886. for (file = file_list; file; file = file->next)
  887. fprintf(out, "\t%s \\\n", file->name);
  888. fprintf(out, "\n%s: $(deps_config)\n\n", autoconf_name);
  889. env_write_dep(out, autoconf_name);
  890. fprintf(out, "\n$(deps_config): ;\n");
  891. fflush(out);
  892. ret = ferror(out); /* error check for all fprintf() calls */
  893. fclose(out);
  894. if (ret)
  895. return -1;
  896. if (rename(tmp, name)) {
  897. perror("rename");
  898. return -1;
  899. }
  900. return 0;
  901. }
  902. static int conf_touch_deps(void)
  903. {
  904. const char *name, *tmp;
  905. struct symbol *sym;
  906. int res, i;
  907. name = conf_get_autoconfig_name();
  908. tmp = strrchr(name, '/');
  909. depfile_prefix_len = tmp ? tmp - name + 1 : 0;
  910. if (depfile_prefix_len + 1 > sizeof(depfile_path))
  911. return -1;
  912. strncpy(depfile_path, name, depfile_prefix_len);
  913. depfile_path[depfile_prefix_len] = 0;
  914. conf_read_simple(name, S_DEF_AUTO);
  915. sym_calc_value(modules_sym);
  916. for_all_symbols(i, sym) {
  917. sym_calc_value(sym);
  918. if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
  919. continue;
  920. if (sym->flags & SYMBOL_WRITE) {
  921. if (sym->flags & SYMBOL_DEF_AUTO) {
  922. /*
  923. * symbol has old and new value,
  924. * so compare them...
  925. */
  926. switch (sym->type) {
  927. case S_BOOLEAN:
  928. case S_TRISTATE:
  929. if (sym_get_tristate_value(sym) ==
  930. sym->def[S_DEF_AUTO].tri)
  931. continue;
  932. break;
  933. case S_STRING:
  934. case S_HEX:
  935. case S_INT:
  936. if (!strcmp(sym_get_string_value(sym),
  937. sym->def[S_DEF_AUTO].val))
  938. continue;
  939. break;
  940. default:
  941. break;
  942. }
  943. } else {
  944. /*
  945. * If there is no old value, only 'no' (unset)
  946. * is allowed as new value.
  947. */
  948. switch (sym->type) {
  949. case S_BOOLEAN:
  950. case S_TRISTATE:
  951. if (sym_get_tristate_value(sym) == no)
  952. continue;
  953. break;
  954. default:
  955. break;
  956. }
  957. }
  958. } else if (!(sym->flags & SYMBOL_DEF_AUTO))
  959. /* There is neither an old nor a new value. */
  960. continue;
  961. /* else
  962. * There is an old value, but no new value ('no' (unset)
  963. * isn't saved in auto.conf, so the old value is always
  964. * different from 'no').
  965. */
  966. res = conf_touch_dep(sym->name);
  967. if (res)
  968. return res;
  969. }
  970. return 0;
  971. }
  972. static int __conf_write_autoconf(const char *filename,
  973. void (*print_symbol)(FILE *, struct symbol *),
  974. const struct comment_style *comment_style)
  975. {
  976. char tmp[PATH_MAX];
  977. FILE *file;
  978. struct symbol *sym;
  979. int ret, i;
  980. if (make_parent_dir(filename))
  981. return -1;
  982. ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename);
  983. if (ret >= sizeof(tmp)) /* check truncation */
  984. return -1;
  985. file = fopen(tmp, "w");
  986. if (!file) {
  987. perror("fopen");
  988. return -1;
  989. }
  990. conf_write_heading(file, comment_style);
  991. for_all_symbols(i, sym)
  992. if ((sym->flags & SYMBOL_WRITE) && sym->name)
  993. print_symbol(file, sym);
  994. fflush(file);
  995. /* check possible errors in conf_write_heading() and print_symbol() */
  996. ret = ferror(file);
  997. fclose(file);
  998. if (ret)
  999. return -1;
  1000. if (rename(tmp, filename)) {
  1001. perror("rename");
  1002. return -1;
  1003. }
  1004. return 0;
  1005. }
  1006. int conf_write_autoconf(int overwrite)
  1007. {
  1008. struct symbol *sym;
  1009. const char *autoconf_name = conf_get_autoconfig_name();
  1010. int ret, i;
  1011. #ifndef OPENWRT_DOES_NOT_WANT_THIS
  1012. return 0;
  1013. #endif
  1014. if (!overwrite && is_present(autoconf_name))
  1015. return 0;
  1016. ret = conf_write_autoconf_cmd(autoconf_name);
  1017. if (ret)
  1018. return -1;
  1019. if (conf_touch_deps())
  1020. return 1;
  1021. for_all_symbols(i, sym)
  1022. sym_calc_value(sym);
  1023. ret = __conf_write_autoconf(conf_get_autoheader_name(),
  1024. print_symbol_for_c,
  1025. &comment_style_c);
  1026. if (ret)
  1027. return ret;
  1028. ret = __conf_write_autoconf(conf_get_rustccfg_name(),
  1029. print_symbol_for_rustccfg,
  1030. NULL);
  1031. if (ret)
  1032. return ret;
  1033. /*
  1034. * Create include/config/auto.conf. This must be the last step because
  1035. * Kbuild has a dependency on auto.conf and this marks the successful
  1036. * completion of the previous steps.
  1037. */
  1038. ret = __conf_write_autoconf(conf_get_autoconfig_name(),
  1039. print_symbol_for_autoconf,
  1040. &comment_style_pound);
  1041. if (ret)
  1042. return ret;
  1043. return 0;
  1044. }
  1045. static bool conf_changed;
  1046. static void (*conf_changed_callback)(void);
  1047. void conf_set_changed(bool val)
  1048. {
  1049. bool changed = conf_changed != val;
  1050. conf_changed = val;
  1051. if (conf_changed_callback && changed)
  1052. conf_changed_callback();
  1053. }
  1054. bool conf_get_changed(void)
  1055. {
  1056. return conf_changed;
  1057. }
  1058. void conf_set_changed_callback(void (*fn)(void))
  1059. {
  1060. conf_changed_callback = fn;
  1061. }
  1062. void set_all_choice_values(struct symbol *csym)
  1063. {
  1064. struct property *prop;
  1065. struct symbol *sym;
  1066. struct expr *e;
  1067. prop = sym_get_choice_prop(csym);
  1068. /*
  1069. * Set all non-assinged choice values to no
  1070. */
  1071. expr_list_for_each_sym(prop->expr, e, sym) {
  1072. if (!sym_has_value(sym))
  1073. sym->def[S_DEF_USER].tri = no;
  1074. }
  1075. csym->flags |= SYMBOL_DEF_USER;
  1076. /* clear VALID to get value calculated */
  1077. csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
  1078. }