PageRenderTime 45ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/config/symbol.c

http://github.com/linux4sam/at91bootstrap
C | 1127 lines | 898 code | 168 blank | 61 comment | 239 complexity | b335e31b2da17000568a846f398f3d04 MD5 | raw file
  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. #define LKC_DIRECT_LINK
  11. #include "lkc.h"
  12. struct symbol symbol_yes = {
  13. .name = "y",
  14. .curr = {"y", yes},
  15. .flags = SYMBOL_CONST | SYMBOL_VALID,
  16. }, symbol_mod = {
  17. .name = "m",.curr = {
  18. "m", mod},.flags = SYMBOL_CONST | SYMBOL_VALID,}, symbol_no = {
  19. .name = "n",.curr = {
  20. "n", no},.flags = SYMBOL_CONST | SYMBOL_VALID,}, symbol_empty = {
  21. .name = "",.curr = {
  22. "", no},.flags = SYMBOL_VALID,};
  23. struct symbol *sym_defconfig_list;
  24. struct symbol *modules_sym;
  25. tristate modules_val;
  26. struct expr *sym_env_list;
  27. static void sym_add_default(struct symbol *sym, const char *def)
  28. {
  29. struct property *prop = prop_alloc(P_DEFAULT, sym);
  30. prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
  31. }
  32. void sym_init(void)
  33. {
  34. struct symbol *sym;
  35. struct utsname uts;
  36. static bool inited = false;
  37. if (inited)
  38. return;
  39. inited = true;
  40. uname(&uts);
  41. sym = sym_lookup("UNAME_RELEASE", 0);
  42. sym->type = S_STRING;
  43. sym->flags |= SYMBOL_AUTO;
  44. sym_add_default(sym, uts.release);
  45. }
  46. enum symbol_type sym_get_type(struct symbol *sym)
  47. {
  48. enum symbol_type type = sym->type;
  49. if (type == S_TRISTATE) {
  50. if (sym_is_choice_value(sym) && sym->visible == yes)
  51. type = S_BOOLEAN;
  52. else if (modules_val == no)
  53. type = S_BOOLEAN;
  54. }
  55. return type;
  56. }
  57. const char *sym_type_name(enum symbol_type type)
  58. {
  59. switch (type) {
  60. case S_BOOLEAN:
  61. return "boolean";
  62. case S_TRISTATE:
  63. return "tristate";
  64. case S_INT:
  65. return "integer";
  66. case S_HEX:
  67. return "hex";
  68. case S_STRING:
  69. return "string";
  70. case S_UNKNOWN:
  71. return "unknown";
  72. case S_OTHER:
  73. break;
  74. }
  75. return "???";
  76. }
  77. struct property *sym_get_choice_prop(struct symbol *sym)
  78. {
  79. struct property *prop;
  80. for_all_choices(sym, prop)
  81. return prop;
  82. return NULL;
  83. }
  84. struct property *sym_get_env_prop(struct symbol *sym)
  85. {
  86. struct property *prop;
  87. for_all_properties(sym, prop, P_ENV)
  88. return prop;
  89. return NULL;
  90. }
  91. struct property *sym_get_default_prop(struct symbol *sym)
  92. {
  93. struct property *prop;
  94. for_all_defaults(sym, prop) {
  95. prop->visible.tri = expr_calc_value(prop->visible.expr);
  96. if (prop->visible.tri != no)
  97. return prop;
  98. }
  99. return NULL;
  100. }
  101. static struct property *sym_get_range_prop(struct symbol *sym)
  102. {
  103. struct property *prop;
  104. for_all_properties(sym, prop, P_RANGE) {
  105. prop->visible.tri = expr_calc_value(prop->visible.expr);
  106. if (prop->visible.tri != no)
  107. return prop;
  108. }
  109. return NULL;
  110. }
  111. static int sym_get_range_val(struct symbol *sym, int base)
  112. {
  113. sym_calc_value(sym);
  114. switch (sym->type) {
  115. case S_INT:
  116. base = 10;
  117. break;
  118. case S_HEX:
  119. base = 16;
  120. break;
  121. default:
  122. break;
  123. }
  124. return strtol(sym->curr.val, NULL, base);
  125. }
  126. static void sym_validate_range(struct symbol *sym)
  127. {
  128. struct property *prop;
  129. int base, val, val2;
  130. char str[64];
  131. switch (sym->type) {
  132. case S_INT:
  133. base = 10;
  134. break;
  135. case S_HEX:
  136. base = 16;
  137. break;
  138. default:
  139. return;
  140. }
  141. prop = sym_get_range_prop(sym);
  142. if (!prop)
  143. return;
  144. val = strtol(sym->curr.val, NULL, base);
  145. val2 = sym_get_range_val(prop->expr->left.sym, base);
  146. if (val >= val2) {
  147. val2 = sym_get_range_val(prop->expr->right.sym, base);
  148. if (val <= val2)
  149. return;
  150. }
  151. if (sym->type == S_INT)
  152. sprintf(str, "%d", val2);
  153. else
  154. sprintf(str, "0x%x", val2);
  155. sym->curr.val = strdup(str);
  156. }
  157. static void sym_calc_visibility(struct symbol *sym)
  158. {
  159. struct property *prop;
  160. tristate tri;
  161. /*
  162. * any prompt visible?
  163. */
  164. tri = no;
  165. for_all_prompts(sym, prop) {
  166. prop->visible.tri = expr_calc_value(prop->visible.expr);
  167. tri = EXPR_OR(tri, prop->visible.tri);
  168. }
  169. if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
  170. tri = yes;
  171. if (sym->visible != tri) {
  172. sym->visible = tri;
  173. sym_set_changed(sym);
  174. }
  175. if (sym_is_choice_value(sym))
  176. return;
  177. tri = no;
  178. if (sym->rev_dep.expr)
  179. tri = expr_calc_value(sym->rev_dep.expr);
  180. if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
  181. tri = yes;
  182. if (sym->rev_dep.tri != tri) {
  183. sym->rev_dep.tri = tri;
  184. sym_set_changed(sym);
  185. }
  186. }
  187. /*
  188. * Find the default symbol for a choice.
  189. * First try the default values for the choice symbol
  190. * Next locate the first visible choice value
  191. * Return NULL if none was found
  192. */
  193. struct symbol *sym_choice_default(struct symbol *sym)
  194. {
  195. struct symbol *def_sym;
  196. struct property *prop;
  197. struct expr *e;
  198. /*
  199. * any of the defaults visible?
  200. */
  201. for_all_defaults(sym, prop) {
  202. prop->visible.tri = expr_calc_value(prop->visible.expr);
  203. if (prop->visible.tri == no)
  204. continue;
  205. def_sym = prop_get_symbol(prop);
  206. sym_calc_visibility(def_sym);
  207. if (def_sym->visible != no)
  208. return def_sym;
  209. }
  210. /*
  211. * just get the first visible value
  212. */
  213. prop = sym_get_choice_prop(sym);
  214. expr_list_for_each_sym(prop->expr, e, def_sym) {
  215. sym_calc_visibility(def_sym);
  216. if (def_sym->visible != no)
  217. return def_sym;
  218. }
  219. /* failed to locate any defaults */
  220. return NULL;
  221. }
  222. static struct symbol *sym_calc_choice(struct symbol *sym)
  223. {
  224. struct symbol *def_sym;
  225. struct property *prop;
  226. struct expr *e;
  227. /* first calculate all choice values' visibilities */
  228. prop = sym_get_choice_prop(sym);
  229. expr_list_for_each_sym(prop->expr, e, def_sym)
  230. sym_calc_visibility(def_sym);
  231. /* is the user choice visible? */
  232. def_sym = sym->def[S_DEF_USER].val;
  233. if (def_sym && def_sym->visible != no)
  234. return def_sym;
  235. def_sym = sym_choice_default(sym);
  236. if (def_sym == NULL)
  237. /* no choice? reset tristate value */
  238. sym->curr.tri = no;
  239. return def_sym;
  240. }
  241. void sym_calc_value(struct symbol *sym)
  242. {
  243. struct symbol_value newval, oldval;
  244. struct property *prop;
  245. struct expr *e;
  246. if (!sym)
  247. return;
  248. if (sym->flags & SYMBOL_VALID)
  249. return;
  250. sym->flags |= SYMBOL_VALID;
  251. oldval = sym->curr;
  252. switch (sym->type) {
  253. case S_INT:
  254. case S_HEX:
  255. case S_STRING:
  256. newval = symbol_empty.curr;
  257. break;
  258. case S_BOOLEAN:
  259. case S_TRISTATE:
  260. newval = symbol_no.curr;
  261. break;
  262. default:
  263. sym->curr.val = sym->name;
  264. sym->curr.tri = no;
  265. return;
  266. }
  267. if (!sym_is_choice_value(sym))
  268. sym->flags &= ~SYMBOL_WRITE;
  269. sym_calc_visibility(sym);
  270. /*
  271. * set default if recursively called
  272. */
  273. sym->curr = newval;
  274. switch (sym_get_type(sym)) {
  275. case S_BOOLEAN:
  276. case S_TRISTATE:
  277. if (sym_is_choice_value(sym) && sym->visible == yes) {
  278. prop = sym_get_choice_prop(sym);
  279. newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
  280. } else {
  281. if (sym->visible != no) {
  282. /*
  283. * if the symbol is visible use the user value
  284. * * if available, otherwise try the default value
  285. */
  286. sym->flags |= SYMBOL_WRITE;
  287. if (sym_has_value(sym)) {
  288. newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
  289. sym->visible);
  290. goto calc_newval;
  291. }
  292. }
  293. if (sym->rev_dep.tri != no)
  294. sym->flags |= SYMBOL_WRITE;
  295. if (!sym_is_choice(sym)) {
  296. prop = sym_get_default_prop(sym);
  297. if (prop) {
  298. sym->flags |= SYMBOL_WRITE;
  299. newval.tri = EXPR_AND(expr_calc_value(prop->expr),
  300. prop->visible.tri);
  301. }
  302. }
  303. calc_newval:
  304. newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
  305. }
  306. if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
  307. newval.tri = yes;
  308. break;
  309. case S_STRING:
  310. case S_HEX:
  311. case S_INT:
  312. if (sym->visible != no) {
  313. sym->flags |= SYMBOL_WRITE;
  314. if (sym_has_value(sym)) {
  315. newval.val = sym->def[S_DEF_USER].val;
  316. break;
  317. }
  318. }
  319. prop = sym_get_default_prop(sym);
  320. if (prop) {
  321. struct symbol *ds = prop_get_symbol(prop);
  322. if (ds) {
  323. sym->flags |= SYMBOL_WRITE;
  324. sym_calc_value(ds);
  325. newval.val = ds->curr.val;
  326. }
  327. }
  328. break;
  329. default:
  330. ;
  331. }
  332. sym->curr = newval;
  333. if (sym_is_choice(sym) && newval.tri == yes)
  334. sym->curr.val = sym_calc_choice(sym);
  335. sym_validate_range(sym);
  336. if (memcmp(&oldval, &sym->curr, sizeof (oldval))) {
  337. sym_set_changed(sym);
  338. if (modules_sym == sym) {
  339. sym_set_all_changed();
  340. modules_val = modules_sym->curr.tri;
  341. }
  342. }
  343. if (sym_is_choice(sym)) {
  344. struct symbol *choice_sym;
  345. int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
  346. prop = sym_get_choice_prop(sym);
  347. expr_list_for_each_sym(prop->expr, e, choice_sym) {
  348. choice_sym->flags |= flags;
  349. if (flags & SYMBOL_CHANGED)
  350. sym_set_changed(choice_sym);
  351. }
  352. }
  353. if (sym->flags & SYMBOL_AUTO)
  354. sym->flags &= ~SYMBOL_WRITE;
  355. }
  356. void sym_clear_all_valid(void)
  357. {
  358. struct symbol *sym;
  359. int i;
  360. for_all_symbols(i, sym)
  361. sym->flags &= ~SYMBOL_VALID;
  362. sym_add_change_count(1);
  363. if (modules_sym)
  364. sym_calc_value(modules_sym);
  365. }
  366. void sym_set_changed(struct symbol *sym)
  367. {
  368. struct property *prop;
  369. sym->flags |= SYMBOL_CHANGED;
  370. for (prop = sym->prop; prop; prop = prop->next) {
  371. if (prop->menu)
  372. prop->menu->flags |= MENU_CHANGED;
  373. }
  374. }
  375. void sym_set_all_changed(void)
  376. {
  377. struct symbol *sym;
  378. int i;
  379. for_all_symbols(i, sym)
  380. sym_set_changed(sym);
  381. }
  382. bool sym_tristate_within_range(struct symbol *sym, tristate val)
  383. {
  384. int type = sym_get_type(sym);
  385. if (sym->visible == no)
  386. return false;
  387. if (type != S_BOOLEAN && type != S_TRISTATE)
  388. return false;
  389. if (type == S_BOOLEAN && val == mod)
  390. return false;
  391. if (sym->visible <= sym->rev_dep.tri)
  392. return false;
  393. if (sym_is_choice_value(sym) && sym->visible == yes)
  394. return val == yes;
  395. return val >= sym->rev_dep.tri && val <= sym->visible;
  396. }
  397. bool sym_set_tristate_value(struct symbol * sym, tristate val)
  398. {
  399. tristate oldval = sym_get_tristate_value(sym);
  400. if (oldval != val && !sym_tristate_within_range(sym, val))
  401. return false;
  402. if (!(sym->flags & SYMBOL_DEF_USER)) {
  403. sym->flags |= SYMBOL_DEF_USER;
  404. sym_set_changed(sym);
  405. }
  406. /*
  407. * setting a choice value also resets the new flag of the choice
  408. * symbol and all other choice values.
  409. */
  410. if (sym_is_choice_value(sym) && val == yes) {
  411. struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
  412. struct property *prop;
  413. struct expr *e;
  414. cs->def[S_DEF_USER].val = sym;
  415. cs->flags |= SYMBOL_DEF_USER;
  416. prop = sym_get_choice_prop(cs);
  417. for (e = prop->expr; e; e = e->left.expr) {
  418. if (e->right.sym->visible != no)
  419. e->right.sym->flags |= SYMBOL_DEF_USER;
  420. }
  421. }
  422. sym->def[S_DEF_USER].tri = val;
  423. if (oldval != val)
  424. sym_clear_all_valid();
  425. return true;
  426. }
  427. tristate sym_toggle_tristate_value(struct symbol * sym)
  428. {
  429. tristate oldval, newval;
  430. oldval = newval = sym_get_tristate_value(sym);
  431. do {
  432. switch (newval) {
  433. case no:
  434. newval = mod;
  435. break;
  436. case mod:
  437. newval = yes;
  438. break;
  439. case yes:
  440. newval = no;
  441. break;
  442. }
  443. if (sym_set_tristate_value(sym, newval))
  444. break;
  445. } while (oldval != newval);
  446. return newval;
  447. }
  448. bool sym_string_valid(struct symbol * sym, const char *str)
  449. {
  450. signed char ch;
  451. switch (sym->type) {
  452. case S_STRING:
  453. return true;
  454. case S_INT:
  455. ch = *str++;
  456. if (ch == '-')
  457. ch = *str++;
  458. if (!isdigit(ch))
  459. return false;
  460. if (ch == '0' && *str != 0)
  461. return false;
  462. while ((ch = *str++)) {
  463. if (!isdigit(ch))
  464. return false;
  465. }
  466. return true;
  467. case S_HEX:
  468. if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
  469. str += 2;
  470. ch = *str++;
  471. do {
  472. if (!isxdigit(ch))
  473. return false;
  474. } while ((ch = *str++));
  475. return true;
  476. case S_BOOLEAN:
  477. case S_TRISTATE:
  478. switch (str[0]) {
  479. case 'y':
  480. case 'Y':
  481. case 'm':
  482. case 'M':
  483. case 'n':
  484. case 'N':
  485. return true;
  486. }
  487. return false;
  488. default:
  489. return false;
  490. }
  491. }
  492. bool sym_string_within_range(struct symbol * sym, const char *str)
  493. {
  494. struct property *prop;
  495. int val;
  496. switch (sym->type) {
  497. case S_STRING:
  498. return sym_string_valid(sym, str);
  499. case S_INT:
  500. if (!sym_string_valid(sym, str))
  501. return false;
  502. prop = sym_get_range_prop(sym);
  503. if (!prop)
  504. return true;
  505. val = strtol(str, NULL, 10);
  506. return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
  507. val <= sym_get_range_val(prop->expr->right.sym, 10);
  508. case S_HEX:
  509. if (!sym_string_valid(sym, str))
  510. return false;
  511. prop = sym_get_range_prop(sym);
  512. if (!prop)
  513. return true;
  514. val = strtol(str, NULL, 16);
  515. return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
  516. val <= sym_get_range_val(prop->expr->right.sym, 16);
  517. case S_BOOLEAN:
  518. case S_TRISTATE:
  519. switch (str[0]) {
  520. case 'y':
  521. case 'Y':
  522. return sym_tristate_within_range(sym, yes);
  523. case 'm':
  524. case 'M':
  525. return sym_tristate_within_range(sym, mod);
  526. case 'n':
  527. case 'N':
  528. return sym_tristate_within_range(sym, no);
  529. }
  530. return false;
  531. default:
  532. return false;
  533. }
  534. }
  535. bool sym_set_string_value(struct symbol * sym, const char *newval)
  536. {
  537. const char *oldval;
  538. char *val;
  539. int size;
  540. switch (sym->type) {
  541. case S_BOOLEAN:
  542. case S_TRISTATE:
  543. switch (newval[0]) {
  544. case 'y':
  545. case 'Y':
  546. return sym_set_tristate_value(sym, yes);
  547. case 'm':
  548. case 'M':
  549. return sym_set_tristate_value(sym, mod);
  550. case 'n':
  551. case 'N':
  552. return sym_set_tristate_value(sym, no);
  553. }
  554. return false;
  555. default:
  556. ;
  557. }
  558. if (!sym_string_within_range(sym, newval))
  559. return false;
  560. if (!(sym->flags & SYMBOL_DEF_USER)) {
  561. sym->flags |= SYMBOL_DEF_USER;
  562. sym_set_changed(sym);
  563. }
  564. oldval = sym->def[S_DEF_USER].val;
  565. size = strlen(newval) + 1;
  566. if (sym->type == S_HEX
  567. && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
  568. size += 2;
  569. sym->def[S_DEF_USER].val = val = malloc(size);
  570. *val++ = '0';
  571. *val++ = 'x';
  572. } else if (!oldval || strcmp(oldval, newval))
  573. sym->def[S_DEF_USER].val = val = malloc(size);
  574. else
  575. return true;
  576. strcpy(val, newval);
  577. free((void *)oldval);
  578. sym_clear_all_valid();
  579. return true;
  580. }
  581. /*
  582. * Find the default value associated to a symbol.
  583. * For tristate symbol handle the modules=n case
  584. * in which case "m" becomes "y".
  585. * If the symbol does not have any default then fallback
  586. * to the fixed default values.
  587. */
  588. const char *sym_get_string_default(struct symbol *sym)
  589. {
  590. struct property *prop;
  591. struct symbol *ds;
  592. const char *str;
  593. tristate val;
  594. sym_calc_visibility(sym);
  595. sym_calc_value(modules_sym);
  596. val = symbol_no.curr.tri;
  597. str = symbol_empty.curr.val;
  598. /* If symbol has a default value look it up */
  599. prop = sym_get_default_prop(sym);
  600. if (prop != NULL) {
  601. switch (sym->type) {
  602. case S_BOOLEAN:
  603. case S_TRISTATE:
  604. /* The visibility imay limit the value from yes => mod */
  605. val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
  606. break;
  607. default:
  608. /*
  609. * The following fails to handle the situation
  610. * where a default value is further limited by
  611. * the valid range.
  612. */
  613. ds = prop_get_symbol(prop);
  614. if (ds != NULL) {
  615. sym_calc_value(ds);
  616. str = (const char *)ds->curr.val;
  617. }
  618. }
  619. }
  620. /* Handle select statements */
  621. val = EXPR_OR(val, sym->rev_dep.tri);
  622. /* transpose mod to yes if modules are not enabled */
  623. if (val == mod)
  624. if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
  625. val = yes;
  626. /* transpose mod to yes if type is bool */
  627. if (sym->type == S_BOOLEAN && val == mod)
  628. val = yes;
  629. switch (sym->type) {
  630. case S_BOOLEAN:
  631. case S_TRISTATE:
  632. switch (val) {
  633. case no: return "n";
  634. case mod: return "m";
  635. case yes: return "y";
  636. }
  637. case S_INT:
  638. case S_HEX:
  639. return str;
  640. case S_STRING:
  641. return str;
  642. case S_OTHER:
  643. case S_UNKNOWN:
  644. break;
  645. }
  646. return "";
  647. }
  648. const char *sym_get_string_value(struct symbol *sym)
  649. {
  650. tristate val;
  651. switch (sym->type) {
  652. case S_BOOLEAN:
  653. case S_TRISTATE:
  654. val = sym_get_tristate_value(sym);
  655. switch (val) {
  656. case no:
  657. return "n";
  658. case mod:
  659. return "m";
  660. case yes:
  661. return "y";
  662. }
  663. break;
  664. default:
  665. ;
  666. }
  667. return (const char *)sym->curr.val;
  668. }
  669. bool sym_is_changable(struct symbol *sym)
  670. {
  671. return sym->visible > sym->rev_dep.tri;
  672. }
  673. struct symbol *sym_lookup(const char *name, int flags)
  674. {
  675. struct symbol *symbol;
  676. const char *ptr;
  677. char *new_name;
  678. int hash = 0;
  679. if (name) {
  680. if (name[0] && !name[1]) {
  681. switch (name[0]) {
  682. case 'y':
  683. return &symbol_yes;
  684. case 'm':
  685. return &symbol_mod;
  686. case 'n':
  687. return &symbol_no;
  688. }
  689. }
  690. for (ptr = name; *ptr; ptr++)
  691. hash += *ptr;
  692. hash &= 0xff;
  693. for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
  694. if (!strcmp(symbol->name, name) &&
  695. (flags ? symbol->flags & flags
  696. : !(symbol->flags & (SYMBOL_CONST | SYMBOL_CHOICE))))
  697. return symbol;
  698. }
  699. new_name = strdup(name);
  700. } else {
  701. new_name = NULL;
  702. hash = 256;
  703. }
  704. symbol = malloc(sizeof (*symbol));
  705. memset(symbol, 0, sizeof (*symbol));
  706. symbol->name = new_name;
  707. symbol->type = S_UNKNOWN;
  708. symbol->flags |= flags;
  709. symbol->next = symbol_hash[hash];
  710. symbol_hash[hash] = symbol;
  711. return symbol;
  712. }
  713. struct symbol *sym_find(const char *name)
  714. {
  715. struct symbol *symbol = NULL;
  716. const char *ptr;
  717. int hash = 0;
  718. if (!name)
  719. return NULL;
  720. if (name[0] && !name[1]) {
  721. switch (name[0]) {
  722. case 'y':
  723. return &symbol_yes;
  724. case 'm':
  725. return &symbol_mod;
  726. case 'n':
  727. return &symbol_no;
  728. }
  729. }
  730. for (ptr = name; *ptr; ptr++)
  731. hash += *ptr;
  732. hash &= 0xff;
  733. for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
  734. if (!strcmp(symbol->name, name) && !(symbol->flags & SYMBOL_CONST))
  735. break;
  736. }
  737. return symbol;
  738. }
  739. struct symbol **sym_re_search(const char *pattern)
  740. {
  741. struct symbol *sym, **sym_arr = NULL;
  742. int i, cnt, size;
  743. regex_t re;
  744. cnt = size = 0;
  745. /*
  746. * Skip if empty
  747. */
  748. if (strlen(pattern) == 0)
  749. return NULL;
  750. if (regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB | REG_ICASE))
  751. return NULL;
  752. for_all_symbols(i, sym) {
  753. if (sym->flags & SYMBOL_CONST || !sym->name)
  754. continue;
  755. if (regexec(&re, sym->name, 0, NULL, 0))
  756. continue;
  757. if (cnt + 1 >= size) {
  758. void *tmp = sym_arr;
  759. size += 16;
  760. sym_arr = realloc(sym_arr, size * sizeof (struct symbol *));
  761. if (!sym_arr) {
  762. free(tmp);
  763. return NULL;
  764. }
  765. }
  766. sym_arr[cnt++] = sym;
  767. }
  768. if (sym_arr)
  769. sym_arr[cnt] = NULL;
  770. regfree(&re);
  771. return sym_arr;
  772. }
  773. static struct symbol *sym_check_expr_deps(struct expr *e)
  774. {
  775. struct symbol *sym;
  776. if (!e)
  777. return NULL;
  778. switch (e->type) {
  779. case E_OR:
  780. case E_AND:
  781. sym = sym_check_expr_deps(e->left.expr);
  782. if (sym)
  783. return sym;
  784. return sym_check_expr_deps(e->right.expr);
  785. case E_NOT:
  786. return sym_check_expr_deps(e->left.expr);
  787. case E_EQUAL:
  788. case E_UNEQUAL:
  789. sym = sym_check_deps(e->left.sym);
  790. if (sym)
  791. return sym;
  792. return sym_check_deps(e->right.sym);
  793. case E_SYMBOL:
  794. return sym_check_deps(e->left.sym);
  795. default:
  796. break;
  797. }
  798. printf("Oops! How to check %d?\n", e->type);
  799. return NULL;
  800. }
  801. /* return NULL when dependencies are OK */
  802. static struct symbol *sym_check_sym_deps(struct symbol *sym)
  803. {
  804. struct symbol *sym2;
  805. struct property *prop;
  806. sym2 = sym_check_expr_deps(sym->rev_dep.expr);
  807. if (sym2)
  808. return sym2;
  809. for (prop = sym->prop; prop; prop = prop->next) {
  810. if (prop->type == P_CHOICE || prop->type == P_SELECT)
  811. continue;
  812. sym2 = sym_check_expr_deps(prop->visible.expr);
  813. if (sym2)
  814. break;
  815. if (prop->type != P_DEFAULT || sym_is_choice(sym))
  816. continue;
  817. sym2 = sym_check_expr_deps(prop->expr);
  818. if (sym2)
  819. break;
  820. }
  821. return sym2;
  822. }
  823. static struct symbol *sym_check_choice_deps(struct symbol *choice)
  824. {
  825. struct symbol *sym, *sym2;
  826. struct property *prop;
  827. struct expr *e;
  828. prop = sym_get_choice_prop(choice);
  829. expr_list_for_each_sym(prop->expr, e, sym)
  830. sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  831. choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  832. sym2 = sym_check_sym_deps(choice);
  833. choice->flags &= ~SYMBOL_CHECK;
  834. if (sym2)
  835. goto out;
  836. expr_list_for_each_sym(prop->expr, e, sym) {
  837. sym2 = sym_check_sym_deps(sym);
  838. if (sym2) {
  839. fprintf(stderr, " -> %s", sym->name);
  840. break;
  841. }
  842. }
  843. out:
  844. expr_list_for_each_sym(prop->expr, e, sym)
  845. sym->flags &= ~SYMBOL_CHECK;
  846. if (sym2 && sym_is_choice_value(sym2) &&
  847. prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
  848. sym2 = choice;
  849. return sym2;
  850. }
  851. struct symbol *sym_check_deps(struct symbol *sym)
  852. {
  853. struct symbol *sym2;
  854. struct property *prop;
  855. if (sym->flags & SYMBOL_CHECK) {
  856. fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
  857. sym->prop->file->name, sym->prop->lineno,
  858. sym->name ? sym->name : "<choice>");
  859. return sym;
  860. }
  861. if (sym->flags & SYMBOL_CHECKED)
  862. return NULL;
  863. if (sym_is_choice_value(sym)) {
  864. /*
  865. * for choice groups start the check with main choice symbol
  866. */
  867. prop = sym_get_choice_prop(sym);
  868. sym2 = sym_check_deps(prop_get_symbol(prop));
  869. } else if (sym_is_choice(sym)) {
  870. sym2 = sym_check_choice_deps(sym);
  871. } else {
  872. sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  873. sym2 = sym_check_sym_deps(sym);
  874. sym->flags &= ~SYMBOL_CHECK;
  875. }
  876. if (sym2) {
  877. fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>");
  878. if (sym2 == sym) {
  879. fprintf(stderr, "\n");
  880. zconfnerrs++;
  881. sym2 = NULL;
  882. }
  883. }
  884. return sym2;
  885. }
  886. struct property *prop_alloc(enum prop_type type, struct symbol *sym)
  887. {
  888. struct property *prop;
  889. struct property **propp;
  890. prop = malloc(sizeof (*prop));
  891. memset(prop, 0, sizeof (*prop));
  892. prop->type = type;
  893. prop->sym = sym;
  894. prop->file = current_file;
  895. prop->lineno = zconf_lineno();
  896. /*
  897. * append property to the prop list of symbol
  898. */
  899. if (sym) {
  900. for (propp = &sym->prop; *propp; propp = &(*propp)->next) ;
  901. *propp = prop;
  902. }
  903. return prop;
  904. }
  905. struct symbol *prop_get_symbol(struct property *prop)
  906. {
  907. if (prop->expr && (prop->expr->type == E_SYMBOL ||
  908. prop->expr->type == E_LIST))
  909. return prop->expr->left.sym;
  910. return NULL;
  911. }
  912. const char *prop_get_type_name(enum prop_type type)
  913. {
  914. switch (type) {
  915. case P_PROMPT:
  916. return "prompt";
  917. case P_ENV:
  918. return "env";
  919. case P_COMMENT:
  920. return "comment";
  921. case P_MENU:
  922. return "menu";
  923. case P_DEFAULT:
  924. return "default";
  925. case P_CHOICE:
  926. return "choice";
  927. case P_SELECT:
  928. return "select";
  929. case P_RANGE:
  930. return "range";
  931. case P_UNKNOWN:
  932. break;
  933. }
  934. return "unknown";
  935. }
  936. static void prop_add_env(const char *env)
  937. {
  938. struct symbol *sym, *sym2;
  939. struct property *prop;
  940. char *p;
  941. sym = current_entry->sym;
  942. sym->flags |= SYMBOL_AUTO;
  943. for_all_properties(sym, prop, P_ENV) {
  944. sym2 = prop_get_symbol(prop);
  945. if (strcmp(sym2->name, env))
  946. menu_warn(current_entry, "redefining environment symbol from %s",
  947. sym2->name);
  948. return;
  949. }
  950. prop = prop_alloc(P_ENV, sym);
  951. prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
  952. sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
  953. sym_env_list->right.sym = sym;
  954. p = getenv(env);
  955. if (p)
  956. sym_add_default(sym, p);
  957. else
  958. menu_warn(current_entry, "environment variable %s undefined", env);
  959. }