1
0

symbol.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443
  1. /*
  2. * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
  3. * Released under the terms of the GNU GPL v2.0.
  4. */
  5. #include <ctype.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <regex.h>
  9. #include <sys/utsname.h>
  10. #include "lkc.h"
  11. struct symbol symbol_yes = {
  12. .name = "y",
  13. .curr = { "y", yes },
  14. .flags = SYMBOL_CONST|SYMBOL_VALID,
  15. }, symbol_mod = {
  16. .name = "m",
  17. .curr = { "m", mod },
  18. .flags = SYMBOL_CONST|SYMBOL_VALID,
  19. }, symbol_no = {
  20. .name = "n",
  21. .curr = { "n", no },
  22. .flags = SYMBOL_CONST|SYMBOL_VALID,
  23. }, symbol_empty = {
  24. .name = "",
  25. .curr = { "", no },
  26. .flags = SYMBOL_VALID,
  27. };
  28. struct symbol *sym_defconfig_list;
  29. struct symbol *modules_sym;
  30. tristate modules_val;
  31. struct expr *sym_env_list;
  32. static void sym_add_default(struct symbol *sym, const char *def)
  33. {
  34. struct property *prop = prop_alloc(P_DEFAULT, sym);
  35. prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
  36. }
  37. void sym_init(void)
  38. {
  39. struct symbol *sym;
  40. struct utsname uts;
  41. static bool inited = false;
  42. if (inited)
  43. return;
  44. inited = true;
  45. uname(&uts);
  46. sym = sym_lookup("UNAME_RELEASE", 0);
  47. sym->type = S_STRING;
  48. sym->flags |= SYMBOL_AUTO;
  49. sym_add_default(sym, uts.release);
  50. }
  51. enum symbol_type sym_get_type(struct symbol *sym)
  52. {
  53. enum symbol_type type = sym->type;
  54. if (type == S_TRISTATE) {
  55. if (sym_is_choice_value(sym) && sym->visible == yes)
  56. type = S_BOOLEAN;
  57. else if (modules_val == no)
  58. type = S_BOOLEAN;
  59. }
  60. return type;
  61. }
  62. const char *sym_type_name(enum symbol_type type)
  63. {
  64. switch (type) {
  65. case S_BOOLEAN:
  66. return "boolean";
  67. case S_TRISTATE:
  68. return "tristate";
  69. case S_INT:
  70. return "integer";
  71. case S_HEX:
  72. return "hex";
  73. case S_STRING:
  74. return "string";
  75. case S_UNKNOWN:
  76. return "unknown";
  77. case S_OTHER:
  78. break;
  79. }
  80. return "???";
  81. }
  82. struct property *sym_get_choice_prop(struct symbol *sym)
  83. {
  84. struct property *prop;
  85. for_all_choices(sym, prop)
  86. return prop;
  87. return NULL;
  88. }
  89. struct property *sym_get_env_prop(struct symbol *sym)
  90. {
  91. struct property *prop;
  92. for_all_properties(sym, prop, P_ENV)
  93. return prop;
  94. return NULL;
  95. }
  96. struct property *sym_get_default_prop(struct symbol *sym)
  97. {
  98. struct property *prop;
  99. for_all_defaults(sym, prop) {
  100. prop->visible.tri = expr_calc_value(prop->visible.expr);
  101. if (prop->visible.tri != no)
  102. return prop;
  103. }
  104. return NULL;
  105. }
  106. static struct property *sym_get_range_prop(struct symbol *sym)
  107. {
  108. struct property *prop;
  109. for_all_properties(sym, prop, P_RANGE) {
  110. prop->visible.tri = expr_calc_value(prop->visible.expr);
  111. if (prop->visible.tri != no)
  112. return prop;
  113. }
  114. return NULL;
  115. }
  116. static long long sym_get_range_val(struct symbol *sym, int base)
  117. {
  118. sym_calc_value(sym);
  119. switch (sym->type) {
  120. case S_INT:
  121. base = 10;
  122. break;
  123. case S_HEX:
  124. base = 16;
  125. break;
  126. default:
  127. break;
  128. }
  129. return strtoll(sym->curr.val, NULL, base);
  130. }
  131. static void sym_validate_range(struct symbol *sym)
  132. {
  133. struct property *prop;
  134. int base;
  135. long long val, val2;
  136. char str[64];
  137. switch (sym->type) {
  138. case S_INT:
  139. base = 10;
  140. break;
  141. case S_HEX:
  142. base = 16;
  143. break;
  144. default:
  145. return;
  146. }
  147. prop = sym_get_range_prop(sym);
  148. if (!prop)
  149. return;
  150. val = strtoll(sym->curr.val, NULL, base);
  151. val2 = sym_get_range_val(prop->expr->left.sym, base);
  152. if (val >= val2) {
  153. val2 = sym_get_range_val(prop->expr->right.sym, base);
  154. if (val <= val2)
  155. return;
  156. }
  157. if (sym->type == S_INT)
  158. sprintf(str, "%lld", val2);
  159. else
  160. sprintf(str, "0x%llx", val2);
  161. sym->curr.val = strdup(str);
  162. }
  163. static void sym_calc_visibility(struct symbol *sym)
  164. {
  165. struct property *prop;
  166. tristate tri;
  167. struct expr_select_value *esv;
  168. /* any prompt visible? */
  169. tri = no;
  170. for_all_prompts(sym, prop) {
  171. prop->visible.tri = expr_calc_value(prop->visible.expr);
  172. tri = EXPR_OR(tri, prop->visible.tri);
  173. }
  174. if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
  175. tri = yes;
  176. if (sym->visible != tri) {
  177. sym->visible = tri;
  178. sym_set_changed(sym);
  179. }
  180. /* defaulting to "yes" if no explicit "depends on" are given */
  181. tri = yes;
  182. if (sym->dir_dep.expr)
  183. tri = expr_calc_value(sym->dir_dep.expr);
  184. if (tri == mod)
  185. tri = yes;
  186. if (sym->dir_dep.tri != tri) {
  187. sym->dir_dep.tri = tri;
  188. sym_set_changed(sym);
  189. }
  190. tri = no;
  191. if (sym->rev_dep.expr)
  192. tri = expr_calc_value(sym->rev_dep.expr);
  193. if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
  194. tri = yes;
  195. if (sym->rev_dep.tri != tri) {
  196. sym->rev_dep.tri = tri;
  197. sym_set_changed(sym);
  198. }
  199. for (esv = sym->val_dep; esv; esv = esv->next) {
  200. tri = expr_calc_value(esv->expr);
  201. if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
  202. tri = yes;
  203. if (esv->tri != tri) {
  204. esv->tri = tri;
  205. sym_set_changed(sym);
  206. }
  207. }
  208. }
  209. /*
  210. * Find the default symbol for a choice.
  211. * First try the default values for the choice symbol
  212. * Next locate the first visible choice value
  213. * Return NULL if none was found
  214. */
  215. struct symbol *sym_choice_default(struct symbol *sym)
  216. {
  217. struct symbol *def_sym;
  218. struct symbol *ret = NULL;
  219. struct property *prop;
  220. struct expr *e;
  221. /* check to see if any are selected */
  222. prop = sym_get_choice_prop(sym);
  223. expr_list_for_each_sym(prop->expr, e, def_sym)
  224. if (def_sym->rev_dep.tri != no) {
  225. if (ret)
  226. fprintf(stderr, "warning: conflicting selects "
  227. "on choice block: %s\n", sym->name);
  228. else
  229. ret = def_sym;
  230. }
  231. if (ret)
  232. return ret;
  233. /* any of the defaults visible? */
  234. for_all_defaults(sym, prop) {
  235. prop->visible.tri = expr_calc_value(prop->visible.expr);
  236. if (prop->visible.tri == no)
  237. continue;
  238. def_sym = prop_get_symbol(prop);
  239. if (def_sym->visible != no)
  240. return def_sym;
  241. }
  242. /* just get the first visible value */
  243. prop = sym_get_choice_prop(sym);
  244. expr_list_for_each_sym(prop->expr, e, def_sym)
  245. if (def_sym->visible != no)
  246. return def_sym;
  247. /* failed to locate any defaults */
  248. return NULL;
  249. }
  250. static struct symbol *sym_calc_choice(struct symbol *sym)
  251. {
  252. struct symbol *def_sym;
  253. struct property *prop;
  254. struct expr *e;
  255. int flags;
  256. /* first calculate all choice values' visibilities */
  257. flags = sym->flags;
  258. prop = sym_get_choice_prop(sym);
  259. expr_list_for_each_sym(prop->expr, e, def_sym) {
  260. sym_calc_visibility(def_sym);
  261. if (def_sym->visible != no)
  262. flags &= def_sym->flags;
  263. }
  264. sym->flags &= flags | ~SYMBOL_DEF_USER;
  265. /* is the user choice visible? */
  266. def_sym = sym->def[S_DEF_USER].val;
  267. if (def_sym && def_sym->visible != no)
  268. return def_sym;
  269. def_sym = sym_choice_default(sym);
  270. if (def_sym == NULL)
  271. /* no choice? reset tristate value */
  272. sym->curr.tri = no;
  273. return def_sym;
  274. }
  275. void sym_calc_value(struct symbol *sym)
  276. {
  277. struct symbol_value newval, oldval;
  278. struct property *prop;
  279. struct expr *e;
  280. struct expr_select_value *esv;
  281. int got_sel_val;
  282. if (!sym)
  283. return;
  284. if (sym->flags & SYMBOL_VALID)
  285. return;
  286. if (sym_is_choice_value(sym) &&
  287. sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) {
  288. sym->flags &= ~SYMBOL_NEED_SET_CHOICE_VALUES;
  289. prop = sym_get_choice_prop(sym);
  290. sym_calc_value(prop_get_symbol(prop));
  291. }
  292. sym->flags |= SYMBOL_VALID;
  293. oldval = sym->curr;
  294. switch (sym->type) {
  295. case S_INT:
  296. case S_HEX:
  297. case S_STRING:
  298. newval = symbol_empty.curr;
  299. break;
  300. case S_BOOLEAN:
  301. case S_TRISTATE:
  302. newval = symbol_no.curr;
  303. break;
  304. default:
  305. sym->curr.val = sym->name;
  306. sym->curr.tri = no;
  307. return;
  308. }
  309. if (!sym_is_choice_value(sym))
  310. sym->flags &= ~SYMBOL_WRITE;
  311. sym_calc_visibility(sym);
  312. /* set default if recursively called */
  313. sym->curr = newval;
  314. switch (sym_get_type(sym)) {
  315. case S_BOOLEAN:
  316. case S_TRISTATE:
  317. if (sym_is_choice_value(sym) && sym->visible == yes) {
  318. prop = sym_get_choice_prop(sym);
  319. newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
  320. } else {
  321. if (sym->visible != no) {
  322. /* if the symbol is visible use the user value
  323. * if available, otherwise try the default value
  324. */
  325. sym->flags |= SYMBOL_WRITE;
  326. if (sym_has_value(sym)) {
  327. newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
  328. sym->visible);
  329. goto calc_newval;
  330. }
  331. }
  332. if (sym->rev_dep.tri != no)
  333. sym->flags |= SYMBOL_WRITE;
  334. for (esv = sym->val_dep; esv; esv = esv->next)
  335. if (esv->tri != no)
  336. sym->flags |= SYMBOL_WRITE;
  337. if (!sym_is_choice(sym)) {
  338. prop = sym_get_default_prop(sym);
  339. if (prop) {
  340. sym->flags |= SYMBOL_WRITE;
  341. newval.tri = EXPR_AND(expr_calc_value(prop->expr),
  342. prop->visible.tri);
  343. }
  344. }
  345. calc_newval:
  346. if (sym->dir_dep.tri == no) {
  347. if (sym->rev_dep.tri != no) {
  348. fprintf(stderr, "warning: (");
  349. expr_fprint(sym->rev_dep.expr, stderr);
  350. fprintf(stderr, ") selects %s which has unmet direct dependencies (",
  351. sym->name);
  352. expr_fprint(sym->dir_dep.expr, stderr);
  353. fprintf(stderr, ")\n");
  354. }
  355. for (esv = sym->val_dep; esv; esv = esv->next) {
  356. if ((esv->tri != no) &&
  357. (expr_calc_value(esv->value) != no)) {
  358. fprintf(stderr, "warning: (");
  359. expr_fprint(esv->expr, stderr);
  360. fprintf(stderr, ") selects %s (with value ",
  361. sym->name);
  362. expr_fprint(esv->value, stderr);
  363. fprintf(stderr, ") which has unmet direct dependencies (");
  364. expr_fprint(sym->dir_dep.expr, stderr);
  365. fprintf(stderr, ")\n");
  366. }
  367. }
  368. }
  369. newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
  370. for (esv = sym->val_dep; esv; esv = esv->next)
  371. if (esv->tri != no)
  372. newval.tri = EXPR_OR(newval.tri,
  373. expr_calc_value(esv->value));
  374. }
  375. if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
  376. newval.tri = yes;
  377. break;
  378. case S_STRING:
  379. case S_HEX:
  380. case S_INT:
  381. if (sym->visible != no) {
  382. sym->flags |= SYMBOL_WRITE;
  383. if (sym_has_value(sym)) {
  384. newval.val = sym->def[S_DEF_USER].val;
  385. break;
  386. }
  387. }
  388. got_sel_val = 0;
  389. for (esv = sym->val_dep; esv; esv = esv->next) {
  390. if (esv->tri != no) {
  391. struct symbol *ss = esv->value->left.sym;
  392. if (got_sel_val) {
  393. /* warn of more than one value selected */
  394. } else {
  395. sym->flags |= SYMBOL_WRITE;
  396. sym_calc_value(ss);
  397. newval.val = ss->curr.val;
  398. got_sel_val = 1;
  399. }
  400. }
  401. }
  402. if (got_sel_val)
  403. break;
  404. prop = sym_get_default_prop(sym);
  405. if (prop) {
  406. struct symbol *ds = prop_get_symbol(prop);
  407. if (ds) {
  408. sym->flags |= SYMBOL_WRITE;
  409. sym_calc_value(ds);
  410. newval.val = ds->curr.val;
  411. }
  412. }
  413. break;
  414. default:
  415. ;
  416. }
  417. sym->curr = newval;
  418. if (sym_is_choice(sym) && newval.tri == yes)
  419. sym->curr.val = sym_calc_choice(sym);
  420. sym_validate_range(sym);
  421. if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
  422. sym_set_changed(sym);
  423. if (modules_sym == sym) {
  424. sym_set_all_changed();
  425. modules_val = modules_sym->curr.tri;
  426. }
  427. }
  428. if (sym_is_choice(sym)) {
  429. struct symbol *choice_sym;
  430. prop = sym_get_choice_prop(sym);
  431. expr_list_for_each_sym(prop->expr, e, choice_sym) {
  432. if ((sym->flags & SYMBOL_WRITE) &&
  433. choice_sym->visible != no)
  434. choice_sym->flags |= SYMBOL_WRITE;
  435. if (sym->flags & SYMBOL_CHANGED)
  436. sym_set_changed(choice_sym);
  437. }
  438. }
  439. if (sym->flags & SYMBOL_AUTO)
  440. sym->flags &= ~SYMBOL_WRITE;
  441. if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
  442. set_all_choice_values(sym);
  443. }
  444. void sym_clear_all_valid(void)
  445. {
  446. struct symbol *sym;
  447. int i;
  448. for_all_symbols(i, sym)
  449. sym->flags &= ~SYMBOL_VALID;
  450. sym_add_change_count(1);
  451. if (modules_sym)
  452. sym_calc_value(modules_sym);
  453. }
  454. void sym_set_changed(struct symbol *sym)
  455. {
  456. struct property *prop;
  457. sym->flags |= SYMBOL_CHANGED;
  458. for (prop = sym->prop; prop; prop = prop->next) {
  459. if (prop->menu)
  460. prop->menu->flags |= MENU_CHANGED;
  461. }
  462. }
  463. void sym_set_all_changed(void)
  464. {
  465. struct symbol *sym;
  466. int i;
  467. for_all_symbols(i, sym)
  468. sym_set_changed(sym);
  469. }
  470. bool sym_tristate_within_range(struct symbol *sym, tristate val)
  471. {
  472. int type = sym_get_type(sym);
  473. struct expr_select_value *esv;
  474. tristate tri;
  475. if (sym->visible == no)
  476. return false;
  477. if (type != S_BOOLEAN && type != S_TRISTATE)
  478. return false;
  479. if (type == S_BOOLEAN && val == mod)
  480. return false;
  481. tri = sym->rev_dep.tri;
  482. for (esv = sym->val_dep; esv; esv = esv->next)
  483. tri = EXPR_OR(tri, esv->tri);
  484. if (sym->visible <= tri)
  485. return false;
  486. if (sym_is_choice_value(sym) && sym->visible == yes)
  487. return val == yes;
  488. return val >= tri && val <= sym->visible;
  489. }
  490. bool sym_set_tristate_value(struct symbol *sym, tristate val)
  491. {
  492. tristate oldval = sym_get_tristate_value(sym);
  493. if (oldval != val && !sym_tristate_within_range(sym, val))
  494. return false;
  495. if (!(sym->flags & SYMBOL_DEF_USER)) {
  496. sym->flags |= SYMBOL_DEF_USER;
  497. sym_set_changed(sym);
  498. }
  499. /*
  500. * setting a choice value also resets the new flag of the choice
  501. * symbol and all other choice values.
  502. */
  503. if (sym_is_choice_value(sym) && val == yes) {
  504. struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
  505. struct property *prop;
  506. struct expr *e;
  507. cs->def[S_DEF_USER].val = sym;
  508. cs->flags |= SYMBOL_DEF_USER;
  509. prop = sym_get_choice_prop(cs);
  510. for (e = prop->expr; e; e = e->left.expr) {
  511. if (e->right.sym->visible != no)
  512. e->right.sym->flags |= SYMBOL_DEF_USER;
  513. }
  514. }
  515. sym->def[S_DEF_USER].tri = val;
  516. if (oldval != val)
  517. sym_clear_all_valid();
  518. return true;
  519. }
  520. tristate sym_toggle_tristate_value(struct symbol *sym)
  521. {
  522. tristate oldval, newval;
  523. oldval = newval = sym_get_tristate_value(sym);
  524. do {
  525. switch (newval) {
  526. case no:
  527. newval = mod;
  528. break;
  529. case mod:
  530. newval = yes;
  531. break;
  532. case yes:
  533. newval = no;
  534. break;
  535. }
  536. if (sym_set_tristate_value(sym, newval))
  537. break;
  538. } while (oldval != newval);
  539. return newval;
  540. }
  541. bool sym_string_valid(struct symbol *sym, const char *str)
  542. {
  543. signed char ch;
  544. switch (sym->type) {
  545. case S_STRING:
  546. return true;
  547. case S_INT:
  548. ch = *str++;
  549. if (ch == '-')
  550. ch = *str++;
  551. if (!isdigit(ch))
  552. return false;
  553. if (ch == '0' && *str != 0)
  554. return false;
  555. while ((ch = *str++)) {
  556. if (!isdigit(ch))
  557. return false;
  558. }
  559. return true;
  560. case S_HEX:
  561. if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
  562. str += 2;
  563. ch = *str++;
  564. do {
  565. if (!isxdigit(ch))
  566. return false;
  567. } while ((ch = *str++));
  568. return true;
  569. case S_BOOLEAN:
  570. case S_TRISTATE:
  571. switch (str[0]) {
  572. case 'y': case 'Y':
  573. case 'm': case 'M':
  574. case 'n': case 'N':
  575. return true;
  576. }
  577. return false;
  578. default:
  579. return false;
  580. }
  581. }
  582. bool sym_string_within_range(struct symbol *sym, const char *str)
  583. {
  584. struct property *prop;
  585. long long val;
  586. switch (sym->type) {
  587. case S_STRING:
  588. return sym_string_valid(sym, str);
  589. case S_INT:
  590. if (!sym_string_valid(sym, str))
  591. return false;
  592. prop = sym_get_range_prop(sym);
  593. if (!prop)
  594. return true;
  595. val = strtoll(str, NULL, 10);
  596. return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
  597. val <= sym_get_range_val(prop->expr->right.sym, 10);
  598. case S_HEX:
  599. if (!sym_string_valid(sym, str))
  600. return false;
  601. prop = sym_get_range_prop(sym);
  602. if (!prop)
  603. return true;
  604. val = strtoll(str, NULL, 16);
  605. return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
  606. val <= sym_get_range_val(prop->expr->right.sym, 16);
  607. case S_BOOLEAN:
  608. case S_TRISTATE:
  609. switch (str[0]) {
  610. case 'y': case 'Y':
  611. return sym_tristate_within_range(sym, yes);
  612. case 'm': case 'M':
  613. return sym_tristate_within_range(sym, mod);
  614. case 'n': case 'N':
  615. return sym_tristate_within_range(sym, no);
  616. }
  617. return false;
  618. default:
  619. return false;
  620. }
  621. }
  622. bool sym_set_string_value(struct symbol *sym, const char *newval)
  623. {
  624. const char *oldval;
  625. char *val;
  626. int size;
  627. switch (sym->type) {
  628. case S_BOOLEAN:
  629. case S_TRISTATE:
  630. switch (newval[0]) {
  631. case 'y': case 'Y':
  632. return sym_set_tristate_value(sym, yes);
  633. case 'm': case 'M':
  634. return sym_set_tristate_value(sym, mod);
  635. case 'n': case 'N':
  636. return sym_set_tristate_value(sym, no);
  637. }
  638. return false;
  639. default:
  640. ;
  641. }
  642. if (!sym_string_within_range(sym, newval))
  643. return false;
  644. if (!(sym->flags & SYMBOL_DEF_USER)) {
  645. sym->flags |= SYMBOL_DEF_USER;
  646. sym_set_changed(sym);
  647. }
  648. oldval = sym->def[S_DEF_USER].val;
  649. size = strlen(newval) + 1;
  650. if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
  651. size += 2;
  652. sym->def[S_DEF_USER].val = val = xmalloc(size);
  653. *val++ = '0';
  654. *val++ = 'x';
  655. } else if (!oldval || strcmp(oldval, newval))
  656. sym->def[S_DEF_USER].val = val = xmalloc(size);
  657. else
  658. return true;
  659. strcpy(val, newval);
  660. free((void *)oldval);
  661. sym_clear_all_valid();
  662. return true;
  663. }
  664. /*
  665. * Find the default value associated to a symbol.
  666. * For tristate symbol handle the modules=n case
  667. * in which case "m" becomes "y".
  668. * If the symbol does not have any default then fallback
  669. * to the fixed default values.
  670. */
  671. const char *sym_get_string_default(struct symbol *sym)
  672. {
  673. struct property *prop;
  674. struct symbol *ds;
  675. const char *str;
  676. tristate val;
  677. sym_calc_visibility(sym);
  678. sym_calc_value(modules_sym);
  679. val = symbol_no.curr.tri;
  680. str = symbol_empty.curr.val;
  681. /* If symbol has a default value look it up */
  682. prop = sym_get_default_prop(sym);
  683. if (prop != NULL) {
  684. switch (sym->type) {
  685. case S_BOOLEAN:
  686. case S_TRISTATE:
  687. /* The visibility may limit the value from yes => mod */
  688. val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
  689. break;
  690. default:
  691. /*
  692. * The following fails to handle the situation
  693. * where a default value is further limited by
  694. * the valid range.
  695. */
  696. ds = prop_get_symbol(prop);
  697. if (ds != NULL) {
  698. sym_calc_value(ds);
  699. str = (const char *)ds->curr.val;
  700. }
  701. }
  702. }
  703. /* Handle select statements */
  704. val = EXPR_OR(val, sym->rev_dep.tri);
  705. /* transpose mod to yes if modules are not enabled */
  706. if (val == mod)
  707. if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
  708. val = yes;
  709. /* transpose mod to yes if type is bool */
  710. if (sym->type == S_BOOLEAN && val == mod)
  711. val = yes;
  712. switch (sym->type) {
  713. case S_BOOLEAN:
  714. case S_TRISTATE:
  715. switch (val) {
  716. case no: return "n";
  717. case mod: return "m";
  718. case yes: return "y";
  719. }
  720. case S_INT:
  721. case S_HEX:
  722. return str;
  723. case S_STRING:
  724. return str;
  725. case S_OTHER:
  726. case S_UNKNOWN:
  727. break;
  728. }
  729. return "";
  730. }
  731. const char *sym_get_string_value(struct symbol *sym)
  732. {
  733. tristate val;
  734. switch (sym->type) {
  735. case S_BOOLEAN:
  736. case S_TRISTATE:
  737. val = sym_get_tristate_value(sym);
  738. switch (val) {
  739. case no:
  740. return "n";
  741. case mod:
  742. sym_calc_value(modules_sym);
  743. return (modules_sym->curr.tri == no) ? "n" : "m";
  744. case yes:
  745. return "y";
  746. }
  747. break;
  748. default:
  749. ;
  750. }
  751. return (const char *)sym->curr.val;
  752. }
  753. bool sym_is_changable(struct symbol *sym)
  754. {
  755. tristate tri = sym->rev_dep.tri;
  756. struct expr_select_value *esv;
  757. for (esv = sym->val_dep; esv; esv = esv->next)
  758. tri = EXPR_OR(tri, esv->tri);
  759. return sym->visible > tri;
  760. }
  761. static unsigned strhash(const char *s)
  762. {
  763. /* fnv32 hash */
  764. unsigned hash = 2166136261U;
  765. for (; *s; s++)
  766. hash = (hash ^ *s) * 0x01000193;
  767. return hash;
  768. }
  769. struct symbol *sym_lookup(const char *name, int flags)
  770. {
  771. struct symbol *symbol;
  772. char *new_name;
  773. int hash;
  774. if (name) {
  775. if (name[0] && !name[1]) {
  776. switch (name[0]) {
  777. case 'y': return &symbol_yes;
  778. case 'm': return &symbol_mod;
  779. case 'n': return &symbol_no;
  780. }
  781. }
  782. hash = strhash(name) % SYMBOL_HASHSIZE;
  783. for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
  784. if (symbol->name &&
  785. !strcmp(symbol->name, name) &&
  786. (flags ? symbol->flags & flags
  787. : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
  788. return symbol;
  789. }
  790. new_name = strdup(name);
  791. } else {
  792. new_name = NULL;
  793. hash = 0;
  794. }
  795. symbol = xmalloc(sizeof(*symbol));
  796. memset(symbol, 0, sizeof(*symbol));
  797. symbol->name = new_name;
  798. symbol->type = S_UNKNOWN;
  799. symbol->flags |= flags;
  800. symbol->next = symbol_hash[hash];
  801. symbol_hash[hash] = symbol;
  802. return symbol;
  803. }
  804. struct symbol *sym_find(const char *name)
  805. {
  806. struct symbol *symbol = NULL;
  807. int hash = 0;
  808. if (!name)
  809. return NULL;
  810. if (name[0] && !name[1]) {
  811. switch (name[0]) {
  812. case 'y': return &symbol_yes;
  813. case 'm': return &symbol_mod;
  814. case 'n': return &symbol_no;
  815. }
  816. }
  817. hash = strhash(name) % SYMBOL_HASHSIZE;
  818. for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
  819. if (symbol->name &&
  820. !strcmp(symbol->name, name) &&
  821. !(symbol->flags & SYMBOL_CONST))
  822. break;
  823. }
  824. return symbol;
  825. }
  826. /*
  827. * Expand symbol's names embedded in the string given in argument. Symbols'
  828. * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
  829. * the empty string.
  830. */
  831. const char *sym_expand_string_value(const char *in)
  832. {
  833. const char *src;
  834. char *res;
  835. size_t reslen;
  836. reslen = strlen(in) + 1;
  837. res = xmalloc(reslen);
  838. res[0] = '\0';
  839. while ((src = strchr(in, '$'))) {
  840. char *p, name[SYMBOL_MAXLENGTH];
  841. const char *symval = "";
  842. struct symbol *sym;
  843. size_t newlen;
  844. strncat(res, in, src - in);
  845. src++;
  846. p = name;
  847. while (isalnum(*src) || *src == '_')
  848. *p++ = *src++;
  849. *p = '\0';
  850. sym = sym_find(name);
  851. if (sym != NULL) {
  852. sym_calc_value(sym);
  853. symval = sym_get_string_value(sym);
  854. }
  855. newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
  856. if (newlen > reslen) {
  857. reslen = newlen;
  858. res = realloc(res, reslen);
  859. }
  860. strcat(res, symval);
  861. in = src;
  862. }
  863. strcat(res, in);
  864. return res;
  865. }
  866. const char *sym_escape_string_value(const char *in)
  867. {
  868. const char *p;
  869. size_t reslen;
  870. char *res;
  871. size_t l;
  872. reslen = strlen(in) + strlen("\"\"") + 1;
  873. p = in;
  874. for (;;) {
  875. l = strcspn(p, "\"\\");
  876. p += l;
  877. if (p[0] == '\0')
  878. break;
  879. reslen++;
  880. p++;
  881. }
  882. res = xmalloc(reslen);
  883. res[0] = '\0';
  884. strcat(res, "\"");
  885. p = in;
  886. for (;;) {
  887. l = strcspn(p, "\"\\");
  888. strncat(res, p, l);
  889. p += l;
  890. if (p[0] == '\0')
  891. break;
  892. strcat(res, "\\");
  893. strncat(res, p++, 1);
  894. }
  895. strcat(res, "\"");
  896. return res;
  897. }
  898. struct sym_match {
  899. struct symbol *sym;
  900. off_t so, eo;
  901. };
  902. /* Compare matched symbols as thus:
  903. * - first, symbols that match exactly
  904. * - then, alphabetical sort
  905. */
  906. static int sym_rel_comp(const void *sym1, const void *sym2)
  907. {
  908. const struct sym_match *s1 = sym1;
  909. const struct sym_match *s2 = sym2;
  910. int exact1, exact2;
  911. /* Exact match:
  912. * - if matched length on symbol s1 is the length of that symbol,
  913. * then this symbol should come first;
  914. * - if matched length on symbol s2 is the length of that symbol,
  915. * then this symbol should come first.
  916. * Note: since the search can be a regexp, both symbols may match
  917. * exactly; if this is the case, we can't decide which comes first,
  918. * and we fallback to sorting alphabetically.
  919. */
  920. exact1 = (s1->eo - s1->so) == strlen(s1->sym->name);
  921. exact2 = (s2->eo - s2->so) == strlen(s2->sym->name);
  922. if (exact1 && !exact2)
  923. return -1;
  924. if (!exact1 && exact2)
  925. return 1;
  926. /* As a fallback, sort symbols alphabetically */
  927. return strcmp(s1->sym->name, s2->sym->name);
  928. }
  929. struct symbol **sym_re_search(const char *pattern)
  930. {
  931. struct symbol *sym, **sym_arr = NULL;
  932. struct sym_match *sym_match_arr = NULL;
  933. int i, cnt, size;
  934. regex_t re;
  935. regmatch_t match[1];
  936. cnt = size = 0;
  937. /* Skip if empty */
  938. if (strlen(pattern) == 0)
  939. return NULL;
  940. if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE))
  941. return NULL;
  942. for_all_symbols(i, sym) {
  943. if (sym->flags & SYMBOL_CONST || !sym->name)
  944. continue;
  945. if (regexec(&re, sym->name, 1, match, 0))
  946. continue;
  947. if (cnt >= size) {
  948. void *tmp;
  949. size += 16;
  950. tmp = realloc(sym_match_arr, size * sizeof(struct sym_match));
  951. if (!tmp)
  952. goto sym_re_search_free;
  953. sym_match_arr = tmp;
  954. }
  955. sym_calc_value(sym);
  956. /* As regexec returned 0, we know we have a match, so
  957. * we can use match[0].rm_[se]o without further checks
  958. */
  959. sym_match_arr[cnt].so = match[0].rm_so;
  960. sym_match_arr[cnt].eo = match[0].rm_eo;
  961. sym_match_arr[cnt++].sym = sym;
  962. }
  963. if (sym_match_arr) {
  964. qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp);
  965. sym_arr = malloc((cnt+1) * sizeof(struct symbol));
  966. if (!sym_arr)
  967. goto sym_re_search_free;
  968. for (i = 0; i < cnt; i++)
  969. sym_arr[i] = sym_match_arr[i].sym;
  970. sym_arr[cnt] = NULL;
  971. }
  972. sym_re_search_free:
  973. /* sym_match_arr can be NULL if no match, but free(NULL) is OK */
  974. free(sym_match_arr);
  975. regfree(&re);
  976. return sym_arr;
  977. }
  978. /*
  979. * When we check for recursive dependencies we use a stack to save
  980. * current state so we can print out relevant info to user.
  981. * The entries are located on the call stack so no need to free memory.
  982. * Note insert() remove() must always match to properly clear the stack.
  983. */
  984. static struct dep_stack {
  985. struct dep_stack *prev, *next;
  986. struct symbol *sym;
  987. struct property *prop;
  988. struct expr *expr;
  989. } *check_top;
  990. static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
  991. {
  992. memset(stack, 0, sizeof(*stack));
  993. if (check_top)
  994. check_top->next = stack;
  995. stack->prev = check_top;
  996. stack->sym = sym;
  997. check_top = stack;
  998. }
  999. static void dep_stack_remove(void)
  1000. {
  1001. check_top = check_top->prev;
  1002. if (check_top)
  1003. check_top->next = NULL;
  1004. }
  1005. /*
  1006. * Called when we have detected a recursive dependency.
  1007. * check_top point to the top of the stact so we use
  1008. * the ->prev pointer to locate the bottom of the stack.
  1009. */
  1010. static void sym_check_print_recursive(struct symbol *last_sym)
  1011. {
  1012. struct dep_stack *stack;
  1013. struct symbol *sym, *next_sym;
  1014. struct menu *menu = NULL;
  1015. struct property *prop;
  1016. struct dep_stack cv_stack;
  1017. if (sym_is_choice_value(last_sym)) {
  1018. dep_stack_insert(&cv_stack, last_sym);
  1019. last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
  1020. }
  1021. for (stack = check_top; stack != NULL; stack = stack->prev)
  1022. if (stack->sym == last_sym)
  1023. break;
  1024. if (!stack) {
  1025. fprintf(stderr, "unexpected recursive dependency error\n");
  1026. return;
  1027. }
  1028. for (; stack; stack = stack->next) {
  1029. sym = stack->sym;
  1030. next_sym = stack->next ? stack->next->sym : last_sym;
  1031. prop = stack->prop;
  1032. if (prop == NULL)
  1033. prop = stack->sym->prop;
  1034. /* for choice values find the menu entry (used below) */
  1035. if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
  1036. for (prop = sym->prop; prop; prop = prop->next) {
  1037. menu = prop->menu;
  1038. if (prop->menu)
  1039. break;
  1040. }
  1041. }
  1042. if (stack->sym == last_sym)
  1043. fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
  1044. prop->file->name, prop->lineno);
  1045. if (stack->expr) {
  1046. fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
  1047. prop->file->name, prop->lineno,
  1048. sym->name ? sym->name : "<choice>",
  1049. prop_get_type_name(prop->type),
  1050. next_sym->name ? next_sym->name : "<choice>");
  1051. } else if (stack->prop) {
  1052. fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
  1053. prop->file->name, prop->lineno,
  1054. sym->name ? sym->name : "<choice>",
  1055. next_sym->name ? next_sym->name : "<choice>");
  1056. } else if (sym_is_choice(sym)) {
  1057. fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
  1058. menu->file->name, menu->lineno,
  1059. sym->name ? sym->name : "<choice>",
  1060. next_sym->name ? next_sym->name : "<choice>");
  1061. } else if (sym_is_choice_value(sym)) {
  1062. fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
  1063. menu->file->name, menu->lineno,
  1064. sym->name ? sym->name : "<choice>",
  1065. next_sym->name ? next_sym->name : "<choice>");
  1066. } else {
  1067. fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
  1068. prop->file->name, prop->lineno,
  1069. sym->name ? sym->name : "<choice>",
  1070. next_sym->name ? next_sym->name : "<choice>");
  1071. }
  1072. }
  1073. if (check_top == &cv_stack)
  1074. dep_stack_remove();
  1075. }
  1076. static struct symbol *sym_check_expr_deps(struct expr *e)
  1077. {
  1078. struct symbol *sym;
  1079. if (!e)
  1080. return NULL;
  1081. switch (e->type) {
  1082. case E_OR:
  1083. case E_AND:
  1084. sym = sym_check_expr_deps(e->left.expr);
  1085. if (sym)
  1086. return sym;
  1087. return sym_check_expr_deps(e->right.expr);
  1088. case E_NOT:
  1089. return sym_check_expr_deps(e->left.expr);
  1090. case E_EQUAL:
  1091. case E_UNEQUAL:
  1092. sym = sym_check_deps(e->left.sym);
  1093. if (sym)
  1094. return sym;
  1095. return sym_check_deps(e->right.sym);
  1096. case E_SYMBOL:
  1097. return sym_check_deps(e->left.sym);
  1098. default:
  1099. break;
  1100. }
  1101. printf("Oops! How to check %d?\n", e->type);
  1102. return NULL;
  1103. }
  1104. /* return NULL when dependencies are OK */
  1105. static struct symbol *sym_check_sym_deps(struct symbol *sym)
  1106. {
  1107. struct symbol *sym2;
  1108. struct property *prop;
  1109. struct dep_stack stack;
  1110. dep_stack_insert(&stack, sym);
  1111. sym2 = sym_check_expr_deps(sym->rev_dep.expr);
  1112. if (sym2)
  1113. goto out;
  1114. for (prop = sym->prop; prop; prop = prop->next) {
  1115. if (prop->type == P_CHOICE || prop->type == P_SELECT)
  1116. continue;
  1117. stack.prop = prop;
  1118. sym2 = sym_check_expr_deps(prop->visible.expr);
  1119. if (sym2)
  1120. break;
  1121. if (prop->type != P_DEFAULT || sym_is_choice(sym))
  1122. continue;
  1123. stack.expr = prop->expr;
  1124. sym2 = sym_check_expr_deps(prop->expr);
  1125. if (sym2)
  1126. break;
  1127. stack.expr = NULL;
  1128. }
  1129. out:
  1130. dep_stack_remove();
  1131. return sym2;
  1132. }
  1133. static struct symbol *sym_check_choice_deps(struct symbol *choice)
  1134. {
  1135. struct symbol *sym, *sym2;
  1136. struct property *prop;
  1137. struct expr *e;
  1138. struct dep_stack stack;
  1139. dep_stack_insert(&stack, choice);
  1140. prop = sym_get_choice_prop(choice);
  1141. expr_list_for_each_sym(prop->expr, e, sym)
  1142. sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  1143. choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  1144. sym2 = sym_check_sym_deps(choice);
  1145. choice->flags &= ~SYMBOL_CHECK;
  1146. if (sym2)
  1147. goto out;
  1148. expr_list_for_each_sym(prop->expr, e, sym) {
  1149. sym2 = sym_check_sym_deps(sym);
  1150. if (sym2)
  1151. break;
  1152. }
  1153. out:
  1154. expr_list_for_each_sym(prop->expr, e, sym)
  1155. sym->flags &= ~SYMBOL_CHECK;
  1156. if (sym2 && sym_is_choice_value(sym2) &&
  1157. prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
  1158. sym2 = choice;
  1159. dep_stack_remove();
  1160. return sym2;
  1161. }
  1162. struct symbol *sym_check_deps(struct symbol *sym)
  1163. {
  1164. struct symbol *sym2;
  1165. struct property *prop;
  1166. if (sym->flags & SYMBOL_CHECK) {
  1167. sym_check_print_recursive(sym);
  1168. return sym;
  1169. }
  1170. if (sym->flags & SYMBOL_CHECKED)
  1171. return NULL;
  1172. if (sym_is_choice_value(sym)) {
  1173. struct dep_stack stack;
  1174. /* for choice groups start the check with main choice symbol */
  1175. dep_stack_insert(&stack, sym);
  1176. prop = sym_get_choice_prop(sym);
  1177. sym2 = sym_check_deps(prop_get_symbol(prop));
  1178. dep_stack_remove();
  1179. } else if (sym_is_choice(sym)) {
  1180. sym2 = sym_check_choice_deps(sym);
  1181. } else {
  1182. sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  1183. sym2 = sym_check_sym_deps(sym);
  1184. sym->flags &= ~SYMBOL_CHECK;
  1185. }
  1186. if (sym2 && sym2 == sym)
  1187. sym2 = NULL;
  1188. return sym2;
  1189. }
  1190. struct property *prop_alloc(enum prop_type type, struct symbol *sym)
  1191. {
  1192. struct property *prop;
  1193. struct property **propp;
  1194. prop = xmalloc(sizeof(*prop));
  1195. memset(prop, 0, sizeof(*prop));
  1196. prop->type = type;
  1197. prop->sym = sym;
  1198. prop->file = current_file;
  1199. prop->lineno = zconf_lineno();
  1200. /* append property to the prop list of symbol */
  1201. if (sym) {
  1202. for (propp = &sym->prop; *propp; propp = &(*propp)->next)
  1203. ;
  1204. *propp = prop;
  1205. }
  1206. return prop;
  1207. }
  1208. struct symbol *prop_get_symbol(struct property *prop)
  1209. {
  1210. if (prop->expr && (prop->expr->type == E_SYMBOL ||
  1211. prop->expr->type == E_LIST))
  1212. return prop->expr->left.sym;
  1213. return NULL;
  1214. }
  1215. const char *prop_get_type_name(enum prop_type type)
  1216. {
  1217. switch (type) {
  1218. case P_PROMPT:
  1219. return "prompt";
  1220. case P_ENV:
  1221. return "env";
  1222. case P_COMMENT:
  1223. return "comment";
  1224. case P_MENU:
  1225. return "menu";
  1226. case P_DEFAULT:
  1227. return "default";
  1228. case P_CHOICE:
  1229. return "choice";
  1230. case P_SELECT:
  1231. return "select";
  1232. case P_RANGE:
  1233. return "range";
  1234. case P_SYMBOL:
  1235. return "symbol";
  1236. case P_UNKNOWN:
  1237. break;
  1238. }
  1239. return "unknown";
  1240. }
  1241. static void prop_add_env(const char *env)
  1242. {
  1243. struct symbol *sym, *sym2;
  1244. struct property *prop;
  1245. char *p;
  1246. sym = current_entry->sym;
  1247. sym->flags |= SYMBOL_AUTO;
  1248. for_all_properties(sym, prop, P_ENV) {
  1249. sym2 = prop_get_symbol(prop);
  1250. if (strcmp(sym2->name, env))
  1251. menu_warn(current_entry, "redefining environment symbol from %s",
  1252. sym2->name);
  1253. return;
  1254. }
  1255. prop = prop_alloc(P_ENV, sym);
  1256. prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
  1257. sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
  1258. sym_env_list->right.sym = sym;
  1259. p = getenv(env);
  1260. if (p)
  1261. sym_add_default(sym, p);
  1262. else
  1263. menu_warn(current_entry, "environment variable %s undefined", env);
  1264. }