symbol.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  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. #define LKC_DIRECT_LINK
  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. 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, 1));
  36. }
  37. void sym_init(void)
  38. {
  39. struct symbol *sym;
  40. char *p;
  41. static bool inited = false;
  42. if (inited)
  43. return;
  44. inited = true;
  45. p = getenv("VERSION");
  46. if (p) {
  47. sym = sym_lookup("VERSION", 0);
  48. sym->type = S_STRING;
  49. sym->flags |= SYMBOL_AUTO;
  50. sym_add_default(sym, p);
  51. }
  52. }
  53. enum symbol_type sym_get_type(struct symbol *sym)
  54. {
  55. enum symbol_type type = sym->type;
  56. if (type == S_TRISTATE) {
  57. if (sym_is_choice_value(sym) && sym->visible == yes)
  58. type = S_BOOLEAN;
  59. else if (modules_val == no)
  60. type = S_BOOLEAN;
  61. }
  62. return type;
  63. }
  64. const char *sym_type_name(enum symbol_type type)
  65. {
  66. switch (type) {
  67. case S_BOOLEAN:
  68. return "boolean";
  69. case S_TRISTATE:
  70. return "tristate";
  71. case S_INT:
  72. return "integer";
  73. case S_HEX:
  74. return "hex";
  75. case S_STRING:
  76. return "string";
  77. case S_UNKNOWN:
  78. return "unknown";
  79. case S_OTHER:
  80. break;
  81. }
  82. return "???";
  83. }
  84. struct property *sym_get_choice_prop(struct symbol *sym)
  85. {
  86. struct property *prop;
  87. for_all_choices(sym, prop)
  88. return prop;
  89. return NULL;
  90. }
  91. struct property *sym_get_env_prop(struct symbol *sym)
  92. {
  93. struct property *prop;
  94. for_all_properties(sym, prop, P_ENV)
  95. return prop;
  96. return NULL;
  97. }
  98. struct property *sym_get_default_prop(struct symbol *sym)
  99. {
  100. struct property *prop;
  101. for_all_defaults(sym, prop) {
  102. prop->visible.tri = expr_calc_value(prop->visible.expr);
  103. if (prop->visible.tri != no)
  104. return prop;
  105. }
  106. return NULL;
  107. }
  108. struct property *sym_get_range_prop(struct symbol *sym)
  109. {
  110. struct property *prop;
  111. for_all_properties(sym, prop, P_RANGE) {
  112. prop->visible.tri = expr_calc_value(prop->visible.expr);
  113. if (prop->visible.tri != no)
  114. return prop;
  115. }
  116. return NULL;
  117. }
  118. static int sym_get_range_val(struct symbol *sym, int base)
  119. {
  120. sym_calc_value(sym);
  121. switch (sym->type) {
  122. case S_INT:
  123. base = 10;
  124. break;
  125. case S_HEX:
  126. base = 16;
  127. break;
  128. default:
  129. break;
  130. }
  131. return strtol(sym->curr.val, NULL, base);
  132. }
  133. static void sym_validate_range(struct symbol *sym)
  134. {
  135. struct property *prop;
  136. int base, val, val2;
  137. char str[64];
  138. switch (sym->type) {
  139. case S_INT:
  140. base = 10;
  141. break;
  142. case S_HEX:
  143. base = 16;
  144. break;
  145. default:
  146. return;
  147. }
  148. prop = sym_get_range_prop(sym);
  149. if (!prop)
  150. return;
  151. val = strtol(sym->curr.val, NULL, base);
  152. val2 = sym_get_range_val(prop->expr->left.sym, base);
  153. if (val >= val2) {
  154. val2 = sym_get_range_val(prop->expr->right.sym, base);
  155. if (val <= val2)
  156. return;
  157. }
  158. if (sym->type == S_INT)
  159. sprintf(str, "%d", val2);
  160. else
  161. sprintf(str, "0x%x", val2);
  162. sym->curr.val = strdup(str);
  163. }
  164. static void sym_calc_visibility(struct symbol *sym)
  165. {
  166. struct property *prop;
  167. tristate tri;
  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. if (sym_is_choice_value(sym))
  181. return;
  182. tri = no;
  183. if (sym->rev_dep.expr)
  184. tri = expr_calc_value(sym->rev_dep.expr);
  185. if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
  186. tri = yes;
  187. if (sym->rev_dep.tri != tri) {
  188. sym->rev_dep.tri = tri;
  189. sym_set_changed(sym);
  190. }
  191. }
  192. static struct symbol *sym_calc_choice(struct symbol *sym)
  193. {
  194. struct symbol *def_sym;
  195. struct property *prop;
  196. struct expr *e;
  197. /* is the user choice visible? */
  198. def_sym = sym->def[S_DEF_USER].val;
  199. if (def_sym) {
  200. sym_calc_visibility(def_sym);
  201. if (def_sym->visible != no)
  202. return def_sym;
  203. }
  204. /* any of the defaults visible? */
  205. for_all_defaults(sym, prop) {
  206. prop->visible.tri = expr_calc_value(prop->visible.expr);
  207. if (prop->visible.tri == no)
  208. continue;
  209. def_sym = prop_get_symbol(prop);
  210. sym_calc_visibility(def_sym);
  211. if (def_sym->visible != no)
  212. return def_sym;
  213. }
  214. /* just get the first visible value */
  215. prop = sym_get_choice_prop(sym);
  216. expr_list_for_each_sym(prop->expr, e, def_sym) {
  217. sym_calc_visibility(def_sym);
  218. if (def_sym->visible != no)
  219. return def_sym;
  220. }
  221. /* no choice? reset tristate value */
  222. sym->curr.tri = no;
  223. return NULL;
  224. }
  225. void sym_calc_value(struct symbol *sym)
  226. {
  227. struct symbol_value newval, oldval;
  228. struct property *prop;
  229. struct expr *e;
  230. if (!sym)
  231. return;
  232. if (sym->flags & SYMBOL_VALID)
  233. return;
  234. sym->flags |= SYMBOL_VALID;
  235. oldval = sym->curr;
  236. switch (sym->type) {
  237. case S_INT:
  238. case S_HEX:
  239. case S_STRING:
  240. newval = symbol_empty.curr;
  241. break;
  242. case S_BOOLEAN:
  243. case S_TRISTATE:
  244. newval = symbol_no.curr;
  245. break;
  246. default:
  247. sym->curr.val = sym->name;
  248. sym->curr.tri = no;
  249. return;
  250. }
  251. if (!sym_is_choice_value(sym))
  252. sym->flags &= ~SYMBOL_WRITE;
  253. sym_calc_visibility(sym);
  254. /* set default if recursively called */
  255. sym->curr = newval;
  256. switch (sym_get_type(sym)) {
  257. case S_BOOLEAN:
  258. case S_TRISTATE:
  259. if (sym_is_choice_value(sym) && sym->visible == yes) {
  260. prop = sym_get_choice_prop(sym);
  261. newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
  262. } else {
  263. if (sym->visible != no) {
  264. /* if the symbol is visible use the user value
  265. * if available, otherwise try the default value
  266. */
  267. sym->flags |= SYMBOL_WRITE;
  268. if (sym_has_value(sym)) {
  269. newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
  270. sym->visible);
  271. goto calc_newval;
  272. }
  273. }
  274. if (sym->rev_dep.tri != no)
  275. sym->flags |= SYMBOL_WRITE;
  276. if (!sym_is_choice(sym)) {
  277. prop = sym_get_default_prop(sym);
  278. if (prop) {
  279. sym->flags |= SYMBOL_WRITE;
  280. newval.tri = EXPR_AND(expr_calc_value(prop->expr),
  281. prop->visible.tri);
  282. }
  283. }
  284. calc_newval:
  285. newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
  286. }
  287. if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
  288. newval.tri = yes;
  289. break;
  290. case S_STRING:
  291. case S_HEX:
  292. case S_INT:
  293. if (sym->visible != no) {
  294. sym->flags |= SYMBOL_WRITE;
  295. if (sym_has_value(sym)) {
  296. newval.val = sym->def[S_DEF_USER].val;
  297. break;
  298. }
  299. }
  300. prop = sym_get_default_prop(sym);
  301. if (prop) {
  302. struct symbol *ds = prop_get_symbol(prop);
  303. if (ds) {
  304. sym->flags |= SYMBOL_WRITE;
  305. sym_calc_value(ds);
  306. newval.val = ds->curr.val;
  307. }
  308. }
  309. break;
  310. default:
  311. ;
  312. }
  313. if (sym->flags & SYMBOL_AUTO)
  314. sym->flags &= ~SYMBOL_WRITE;
  315. sym->curr = newval;
  316. if (sym_is_choice(sym) && newval.tri == yes)
  317. sym->curr.val = sym_calc_choice(sym);
  318. sym_validate_range(sym);
  319. if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
  320. sym_set_changed(sym);
  321. if (modules_sym == sym) {
  322. sym_set_all_changed();
  323. modules_val = modules_sym->curr.tri;
  324. }
  325. }
  326. if (sym_is_choice(sym)) {
  327. struct symbol *choice_sym;
  328. int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
  329. prop = sym_get_choice_prop(sym);
  330. expr_list_for_each_sym(prop->expr, e, choice_sym) {
  331. choice_sym->flags |= flags;
  332. if (flags & SYMBOL_CHANGED)
  333. sym_set_changed(choice_sym);
  334. }
  335. }
  336. }
  337. void sym_clear_all_valid(void)
  338. {
  339. struct symbol *sym;
  340. int i;
  341. for_all_symbols(i, sym)
  342. sym->flags &= ~SYMBOL_VALID;
  343. sym_add_change_count(1);
  344. if (modules_sym)
  345. sym_calc_value(modules_sym);
  346. }
  347. void sym_set_changed(struct symbol *sym)
  348. {
  349. struct property *prop;
  350. sym->flags |= SYMBOL_CHANGED;
  351. for (prop = sym->prop; prop; prop = prop->next) {
  352. if (prop->menu)
  353. prop->menu->flags |= MENU_CHANGED;
  354. }
  355. }
  356. void sym_set_all_changed(void)
  357. {
  358. struct symbol *sym;
  359. int i;
  360. for_all_symbols(i, sym)
  361. sym_set_changed(sym);
  362. }
  363. bool sym_tristate_within_range(struct symbol *sym, tristate val)
  364. {
  365. int type = sym_get_type(sym);
  366. if (sym->visible == no)
  367. return false;
  368. if (type != S_BOOLEAN && type != S_TRISTATE)
  369. return false;
  370. if (type == S_BOOLEAN && val == mod)
  371. return false;
  372. if (sym->visible <= sym->rev_dep.tri)
  373. return false;
  374. if (sym_is_choice_value(sym) && sym->visible == yes)
  375. return val == yes;
  376. return val >= sym->rev_dep.tri && val <= sym->visible;
  377. }
  378. bool sym_set_tristate_value(struct symbol *sym, tristate val)
  379. {
  380. tristate oldval = sym_get_tristate_value(sym);
  381. if (oldval != val && !sym_tristate_within_range(sym, val))
  382. return false;
  383. if (!(sym->flags & SYMBOL_DEF_USER)) {
  384. sym->flags |= SYMBOL_DEF_USER;
  385. sym_set_changed(sym);
  386. }
  387. /*
  388. * setting a choice value also resets the new flag of the choice
  389. * symbol and all other choice values.
  390. */
  391. if (sym_is_choice_value(sym) && val == yes) {
  392. struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
  393. struct property *prop;
  394. struct expr *e;
  395. cs->def[S_DEF_USER].val = sym;
  396. cs->flags |= SYMBOL_DEF_USER;
  397. prop = sym_get_choice_prop(cs);
  398. for (e = prop->expr; e; e = e->left.expr) {
  399. if (e->right.sym->visible != no)
  400. e->right.sym->flags |= SYMBOL_DEF_USER;
  401. }
  402. }
  403. sym->def[S_DEF_USER].tri = val;
  404. if (oldval != val)
  405. sym_clear_all_valid();
  406. return true;
  407. }
  408. tristate sym_toggle_tristate_value(struct symbol *sym)
  409. {
  410. tristate oldval, newval;
  411. oldval = newval = sym_get_tristate_value(sym);
  412. do {
  413. switch (newval) {
  414. case no:
  415. newval = mod;
  416. break;
  417. case mod:
  418. newval = yes;
  419. break;
  420. case yes:
  421. newval = no;
  422. break;
  423. }
  424. if (sym_set_tristate_value(sym, newval))
  425. break;
  426. } while (oldval != newval);
  427. return newval;
  428. }
  429. bool sym_string_valid(struct symbol *sym, const char *str)
  430. {
  431. signed char ch;
  432. switch (sym->type) {
  433. case S_STRING:
  434. return true;
  435. case S_INT:
  436. ch = *str++;
  437. if (ch == '-')
  438. ch = *str++;
  439. if (!isdigit(ch))
  440. return false;
  441. if (ch == '0' && *str != 0)
  442. return false;
  443. while ((ch = *str++)) {
  444. if (!isdigit(ch))
  445. return false;
  446. }
  447. return true;
  448. case S_HEX:
  449. if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
  450. str += 2;
  451. ch = *str++;
  452. do {
  453. if (!isxdigit(ch))
  454. return false;
  455. } while ((ch = *str++));
  456. return true;
  457. case S_BOOLEAN:
  458. case S_TRISTATE:
  459. switch (str[0]) {
  460. case 'y': case 'Y':
  461. case 'm': case 'M':
  462. case 'n': case 'N':
  463. return true;
  464. }
  465. return false;
  466. default:
  467. return false;
  468. }
  469. }
  470. bool sym_string_within_range(struct symbol *sym, const char *str)
  471. {
  472. struct property *prop;
  473. int val;
  474. switch (sym->type) {
  475. case S_STRING:
  476. return sym_string_valid(sym, str);
  477. case S_INT:
  478. if (!sym_string_valid(sym, str))
  479. return false;
  480. prop = sym_get_range_prop(sym);
  481. if (!prop)
  482. return true;
  483. val = strtol(str, NULL, 10);
  484. return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
  485. val <= sym_get_range_val(prop->expr->right.sym, 10);
  486. case S_HEX:
  487. if (!sym_string_valid(sym, str))
  488. return false;
  489. prop = sym_get_range_prop(sym);
  490. if (!prop)
  491. return true;
  492. val = strtol(str, NULL, 16);
  493. return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
  494. val <= sym_get_range_val(prop->expr->right.sym, 16);
  495. case S_BOOLEAN:
  496. case S_TRISTATE:
  497. switch (str[0]) {
  498. case 'y': case 'Y':
  499. return sym_tristate_within_range(sym, yes);
  500. case 'm': case 'M':
  501. return sym_tristate_within_range(sym, mod);
  502. case 'n': case 'N':
  503. return sym_tristate_within_range(sym, no);
  504. }
  505. return false;
  506. default:
  507. return false;
  508. }
  509. }
  510. bool sym_set_string_value(struct symbol *sym, const char *newval)
  511. {
  512. const char *oldval;
  513. char *val;
  514. int size;
  515. switch (sym->type) {
  516. case S_BOOLEAN:
  517. case S_TRISTATE:
  518. switch (newval[0]) {
  519. case 'y': case 'Y':
  520. return sym_set_tristate_value(sym, yes);
  521. case 'm': case 'M':
  522. return sym_set_tristate_value(sym, mod);
  523. case 'n': case 'N':
  524. return sym_set_tristate_value(sym, no);
  525. }
  526. return false;
  527. default:
  528. ;
  529. }
  530. if (!sym_string_within_range(sym, newval))
  531. return false;
  532. if (!(sym->flags & SYMBOL_DEF_USER)) {
  533. sym->flags |= SYMBOL_DEF_USER;
  534. sym_set_changed(sym);
  535. }
  536. oldval = sym->def[S_DEF_USER].val;
  537. size = strlen(newval) + 1;
  538. if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
  539. size += 2;
  540. sym->def[S_DEF_USER].val = val = malloc(size);
  541. *val++ = '0';
  542. *val++ = 'x';
  543. } else if (!oldval || strcmp(oldval, newval))
  544. sym->def[S_DEF_USER].val = val = malloc(size);
  545. else
  546. return true;
  547. strcpy(val, newval);
  548. free((void *)oldval);
  549. sym_clear_all_valid();
  550. return true;
  551. }
  552. const char *sym_get_string_value(struct symbol *sym)
  553. {
  554. tristate val;
  555. switch (sym->type) {
  556. case S_BOOLEAN:
  557. case S_TRISTATE:
  558. val = sym_get_tristate_value(sym);
  559. switch (val) {
  560. case no:
  561. return "n";
  562. case mod:
  563. return "m";
  564. case yes:
  565. return "y";
  566. }
  567. break;
  568. default:
  569. ;
  570. }
  571. return (const char *)sym->curr.val;
  572. }
  573. bool sym_is_changable(struct symbol *sym)
  574. {
  575. return sym->visible > sym->rev_dep.tri;
  576. }
  577. struct symbol *sym_lookup(const char *name, int isconst)
  578. {
  579. struct symbol *symbol;
  580. const char *ptr;
  581. char *new_name;
  582. int hash = 0;
  583. if (name) {
  584. if (name[0] && !name[1]) {
  585. switch (name[0]) {
  586. case 'y': return &symbol_yes;
  587. case 'm': return &symbol_mod;
  588. case 'n': return &symbol_no;
  589. }
  590. }
  591. for (ptr = name; *ptr; ptr++)
  592. hash += *ptr;
  593. hash &= 0xff;
  594. for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
  595. if (!strcmp(symbol->name, name)) {
  596. if ((isconst && symbol->flags & SYMBOL_CONST) ||
  597. (!isconst && !(symbol->flags & SYMBOL_CONST)))
  598. return symbol;
  599. }
  600. }
  601. new_name = strdup(name);
  602. } else {
  603. new_name = NULL;
  604. hash = 256;
  605. }
  606. symbol = malloc(sizeof(*symbol));
  607. memset(symbol, 0, sizeof(*symbol));
  608. symbol->name = new_name;
  609. symbol->type = S_UNKNOWN;
  610. if (isconst)
  611. symbol->flags |= SYMBOL_CONST;
  612. symbol->next = symbol_hash[hash];
  613. symbol_hash[hash] = symbol;
  614. return symbol;
  615. }
  616. struct symbol *sym_find(const char *name)
  617. {
  618. struct symbol *symbol = NULL;
  619. const char *ptr;
  620. int hash = 0;
  621. if (!name)
  622. return NULL;
  623. if (name[0] && !name[1]) {
  624. switch (name[0]) {
  625. case 'y': return &symbol_yes;
  626. case 'm': return &symbol_mod;
  627. case 'n': return &symbol_no;
  628. }
  629. }
  630. for (ptr = name; *ptr; ptr++)
  631. hash += *ptr;
  632. hash &= 0xff;
  633. for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
  634. if (!strcmp(symbol->name, name) &&
  635. !(symbol->flags & SYMBOL_CONST))
  636. break;
  637. }
  638. return symbol;
  639. }
  640. struct symbol **sym_re_search(const char *pattern)
  641. {
  642. struct symbol *sym, **sym_arr = NULL;
  643. int i, cnt, size;
  644. regex_t re;
  645. cnt = size = 0;
  646. /* Skip if empty */
  647. if (strlen(pattern) == 0)
  648. return NULL;
  649. if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
  650. return NULL;
  651. for_all_symbols(i, sym) {
  652. if (sym->flags & SYMBOL_CONST || !sym->name)
  653. continue;
  654. if (regexec(&re, sym->name, 0, NULL, 0))
  655. continue;
  656. if (cnt + 1 >= size) {
  657. void *tmp = sym_arr;
  658. size += 16;
  659. sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
  660. if (!sym_arr) {
  661. free(tmp);
  662. return NULL;
  663. }
  664. }
  665. sym_arr[cnt++] = sym;
  666. }
  667. if (sym_arr)
  668. sym_arr[cnt] = NULL;
  669. regfree(&re);
  670. return sym_arr;
  671. }
  672. struct symbol *sym_check_deps(struct symbol *sym);
  673. static struct symbol *sym_check_expr_deps(struct expr *e)
  674. {
  675. struct symbol *sym;
  676. if (!e)
  677. return NULL;
  678. switch (e->type) {
  679. case E_OR:
  680. case E_AND:
  681. sym = sym_check_expr_deps(e->left.expr);
  682. if (sym)
  683. return sym;
  684. return sym_check_expr_deps(e->right.expr);
  685. case E_NOT:
  686. return sym_check_expr_deps(e->left.expr);
  687. case E_EQUAL:
  688. case E_UNEQUAL:
  689. sym = sym_check_deps(e->left.sym);
  690. if (sym)
  691. return sym;
  692. return sym_check_deps(e->right.sym);
  693. case E_SYMBOL:
  694. return sym_check_deps(e->left.sym);
  695. default:
  696. break;
  697. }
  698. printf("Oops! How to check %d?\n", e->type);
  699. return NULL;
  700. }
  701. /* return NULL when dependencies are OK */
  702. struct symbol *sym_check_deps(struct symbol *sym)
  703. {
  704. struct symbol *sym2;
  705. struct property *prop;
  706. if (sym->flags & SYMBOL_CHECK) {
  707. fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
  708. sym->prop->file->name, sym->prop->lineno, sym->name);
  709. return sym;
  710. }
  711. if (sym->flags & SYMBOL_CHECKED)
  712. return NULL;
  713. sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  714. sym2 = sym_check_expr_deps(sym->rev_dep.expr);
  715. if (sym2)
  716. goto out;
  717. for (prop = sym->prop; prop; prop = prop->next) {
  718. if (prop->type == P_CHOICE || prop->type == P_SELECT)
  719. continue;
  720. sym2 = sym_check_expr_deps(prop->visible.expr);
  721. if (sym2)
  722. goto out;
  723. if (prop->type != P_DEFAULT || sym_is_choice(sym))
  724. continue;
  725. sym2 = sym_check_expr_deps(prop->expr);
  726. if (sym2)
  727. goto out;
  728. }
  729. out:
  730. if (sym2)
  731. fprintf(stderr, " -> %s%s", sym->name, sym2 == sym? "\n": "");
  732. sym->flags &= ~SYMBOL_CHECK;
  733. return sym2;
  734. }
  735. struct property *prop_alloc(enum prop_type type, struct symbol *sym)
  736. {
  737. struct property *prop;
  738. struct property **propp;
  739. prop = malloc(sizeof(*prop));
  740. memset(prop, 0, sizeof(*prop));
  741. prop->type = type;
  742. prop->sym = sym;
  743. prop->file = current_file;
  744. prop->lineno = zconf_lineno();
  745. /* append property to the prop list of symbol */
  746. if (sym) {
  747. for (propp = &sym->prop; *propp; propp = &(*propp)->next)
  748. ;
  749. *propp = prop;
  750. }
  751. return prop;
  752. }
  753. struct symbol *prop_get_symbol(struct property *prop)
  754. {
  755. if (prop->expr && (prop->expr->type == E_SYMBOL ||
  756. prop->expr->type == E_LIST))
  757. return prop->expr->left.sym;
  758. return NULL;
  759. }
  760. const char *prop_get_type_name(enum prop_type type)
  761. {
  762. switch (type) {
  763. case P_PROMPT:
  764. return "prompt";
  765. case P_ENV:
  766. return "env";
  767. case P_COMMENT:
  768. return "comment";
  769. case P_MENU:
  770. return "menu";
  771. case P_DEFAULT:
  772. return "default";
  773. case P_CHOICE:
  774. return "choice";
  775. case P_SELECT:
  776. return "select";
  777. case P_RANGE:
  778. return "range";
  779. case P_UNKNOWN:
  780. break;
  781. }
  782. return "unknown";
  783. }
  784. void prop_add_env(const char *env)
  785. {
  786. struct symbol *sym, *sym2;
  787. struct property *prop;
  788. char *p;
  789. sym = current_entry->sym;
  790. sym->flags |= SYMBOL_AUTO;
  791. for_all_properties(sym, prop, P_ENV) {
  792. sym2 = prop_get_symbol(prop);
  793. if (strcmp(sym2->name, env))
  794. menu_warn(current_entry, "redefining environment symbol from %s",
  795. sym2->name);
  796. return;
  797. }
  798. prop = prop_alloc(P_ENV, sym);
  799. prop->expr = expr_alloc_symbol(sym_lookup(env, 1));
  800. sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
  801. sym_env_list->right.sym = sym;
  802. p = getenv(env);
  803. if (p)
  804. sym_add_default(sym, p);
  805. else
  806. menu_warn(current_entry, "environment variable %s undefined", env);
  807. }