symbol.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  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, SYMBOL_CONST));
  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. sym->curr = newval;
  314. if (sym_is_choice(sym) && newval.tri == yes)
  315. sym->curr.val = sym_calc_choice(sym);
  316. sym_validate_range(sym);
  317. if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
  318. sym_set_changed(sym);
  319. if (modules_sym == sym) {
  320. sym_set_all_changed();
  321. modules_val = modules_sym->curr.tri;
  322. }
  323. }
  324. if (sym_is_choice(sym)) {
  325. struct symbol *choice_sym;
  326. int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
  327. prop = sym_get_choice_prop(sym);
  328. expr_list_for_each_sym(prop->expr, e, choice_sym) {
  329. choice_sym->flags |= flags;
  330. if (flags & SYMBOL_CHANGED)
  331. sym_set_changed(choice_sym);
  332. }
  333. }
  334. if (sym->flags & SYMBOL_AUTO)
  335. sym->flags &= ~SYMBOL_WRITE;
  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 flags)
  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. (flags ? symbol->flags & flags
  597. : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
  598. return symbol;
  599. }
  600. new_name = strdup(name);
  601. } else {
  602. new_name = NULL;
  603. hash = 256;
  604. }
  605. symbol = malloc(sizeof(*symbol));
  606. memset(symbol, 0, sizeof(*symbol));
  607. symbol->name = new_name;
  608. symbol->type = S_UNKNOWN;
  609. symbol->flags |= flags;
  610. symbol->next = symbol_hash[hash];
  611. symbol_hash[hash] = symbol;
  612. return symbol;
  613. }
  614. struct symbol *sym_find(const char *name)
  615. {
  616. struct symbol *symbol = NULL;
  617. const char *ptr;
  618. int hash = 0;
  619. if (!name)
  620. return NULL;
  621. if (name[0] && !name[1]) {
  622. switch (name[0]) {
  623. case 'y': return &symbol_yes;
  624. case 'm': return &symbol_mod;
  625. case 'n': return &symbol_no;
  626. }
  627. }
  628. for (ptr = name; *ptr; ptr++)
  629. hash += *ptr;
  630. hash &= 0xff;
  631. for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
  632. if (!strcmp(symbol->name, name) &&
  633. !(symbol->flags & SYMBOL_CONST))
  634. break;
  635. }
  636. return symbol;
  637. }
  638. struct symbol **sym_re_search(const char *pattern)
  639. {
  640. struct symbol *sym, **sym_arr = NULL;
  641. int i, cnt, size;
  642. regex_t re;
  643. cnt = size = 0;
  644. /* Skip if empty */
  645. if (strlen(pattern) == 0)
  646. return NULL;
  647. if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
  648. return NULL;
  649. for_all_symbols(i, sym) {
  650. if (sym->flags & SYMBOL_CONST || !sym->name)
  651. continue;
  652. if (regexec(&re, sym->name, 0, NULL, 0))
  653. continue;
  654. if (cnt + 1 >= size) {
  655. void *tmp = sym_arr;
  656. size += 16;
  657. sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
  658. if (!sym_arr) {
  659. free(tmp);
  660. return NULL;
  661. }
  662. }
  663. sym_arr[cnt++] = sym;
  664. }
  665. if (sym_arr)
  666. sym_arr[cnt] = NULL;
  667. regfree(&re);
  668. return sym_arr;
  669. }
  670. static struct symbol *sym_check_expr_deps(struct expr *e)
  671. {
  672. struct symbol *sym;
  673. if (!e)
  674. return NULL;
  675. switch (e->type) {
  676. case E_OR:
  677. case E_AND:
  678. sym = sym_check_expr_deps(e->left.expr);
  679. if (sym)
  680. return sym;
  681. return sym_check_expr_deps(e->right.expr);
  682. case E_NOT:
  683. return sym_check_expr_deps(e->left.expr);
  684. case E_EQUAL:
  685. case E_UNEQUAL:
  686. sym = sym_check_deps(e->left.sym);
  687. if (sym)
  688. return sym;
  689. return sym_check_deps(e->right.sym);
  690. case E_SYMBOL:
  691. return sym_check_deps(e->left.sym);
  692. default:
  693. break;
  694. }
  695. printf("Oops! How to check %d?\n", e->type);
  696. return NULL;
  697. }
  698. /* return NULL when dependencies are OK */
  699. static struct symbol *sym_check_sym_deps(struct symbol *sym)
  700. {
  701. struct symbol *sym2;
  702. struct property *prop;
  703. sym2 = sym_check_expr_deps(sym->rev_dep.expr);
  704. if (sym2)
  705. return sym2;
  706. for (prop = sym->prop; prop; prop = prop->next) {
  707. if (prop->type == P_CHOICE || prop->type == P_SELECT)
  708. continue;
  709. sym2 = sym_check_expr_deps(prop->visible.expr);
  710. if (sym2)
  711. break;
  712. if (prop->type != P_DEFAULT || sym_is_choice(sym))
  713. continue;
  714. sym2 = sym_check_expr_deps(prop->expr);
  715. if (sym2)
  716. break;
  717. }
  718. return sym2;
  719. }
  720. static struct symbol *sym_check_choice_deps(struct symbol *choice)
  721. {
  722. struct symbol *sym, *sym2;
  723. struct property *prop;
  724. struct expr *e;
  725. prop = sym_get_choice_prop(choice);
  726. expr_list_for_each_sym(prop->expr, e, sym)
  727. sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  728. choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  729. sym2 = sym_check_sym_deps(choice);
  730. choice->flags &= ~SYMBOL_CHECK;
  731. if (sym2)
  732. goto out;
  733. expr_list_for_each_sym(prop->expr, e, sym) {
  734. sym2 = sym_check_sym_deps(sym);
  735. if (sym2) {
  736. fprintf(stderr, " -> %s", sym->name);
  737. break;
  738. }
  739. }
  740. out:
  741. expr_list_for_each_sym(prop->expr, e, sym)
  742. sym->flags &= ~SYMBOL_CHECK;
  743. if (sym2 && sym_is_choice_value(sym2) &&
  744. prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
  745. sym2 = choice;
  746. return sym2;
  747. }
  748. struct symbol *sym_check_deps(struct symbol *sym)
  749. {
  750. struct symbol *sym2;
  751. struct property *prop;
  752. if (sym->flags & SYMBOL_CHECK) {
  753. fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
  754. sym->prop->file->name, sym->prop->lineno,
  755. sym->name ? sym->name : "<choice>");
  756. return sym;
  757. }
  758. if (sym->flags & SYMBOL_CHECKED)
  759. return NULL;
  760. if (sym_is_choice_value(sym)) {
  761. /* for choice groups start the check with main choice symbol */
  762. prop = sym_get_choice_prop(sym);
  763. sym2 = sym_check_deps(prop_get_symbol(prop));
  764. } else if (sym_is_choice(sym)) {
  765. sym2 = sym_check_choice_deps(sym);
  766. } else {
  767. sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  768. sym2 = sym_check_sym_deps(sym);
  769. sym->flags &= ~SYMBOL_CHECK;
  770. }
  771. if (sym2) {
  772. fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>");
  773. if (sym2 == sym) {
  774. fprintf(stderr, "\n");
  775. zconfnerrs++;
  776. sym2 = NULL;
  777. }
  778. }
  779. return sym2;
  780. }
  781. struct property *prop_alloc(enum prop_type type, struct symbol *sym)
  782. {
  783. struct property *prop;
  784. struct property **propp;
  785. prop = malloc(sizeof(*prop));
  786. memset(prop, 0, sizeof(*prop));
  787. prop->type = type;
  788. prop->sym = sym;
  789. prop->file = current_file;
  790. prop->lineno = zconf_lineno();
  791. /* append property to the prop list of symbol */
  792. if (sym) {
  793. for (propp = &sym->prop; *propp; propp = &(*propp)->next)
  794. ;
  795. *propp = prop;
  796. }
  797. return prop;
  798. }
  799. struct symbol *prop_get_symbol(struct property *prop)
  800. {
  801. if (prop->expr && (prop->expr->type == E_SYMBOL ||
  802. prop->expr->type == E_LIST))
  803. return prop->expr->left.sym;
  804. return NULL;
  805. }
  806. const char *prop_get_type_name(enum prop_type type)
  807. {
  808. switch (type) {
  809. case P_PROMPT:
  810. return "prompt";
  811. case P_ENV:
  812. return "env";
  813. case P_COMMENT:
  814. return "comment";
  815. case P_MENU:
  816. return "menu";
  817. case P_DEFAULT:
  818. return "default";
  819. case P_CHOICE:
  820. return "choice";
  821. case P_SELECT:
  822. return "select";
  823. case P_RANGE:
  824. return "range";
  825. case P_UNKNOWN:
  826. break;
  827. }
  828. return "unknown";
  829. }
  830. void prop_add_env(const char *env)
  831. {
  832. struct symbol *sym, *sym2;
  833. struct property *prop;
  834. char *p;
  835. sym = current_entry->sym;
  836. sym->flags |= SYMBOL_AUTO;
  837. for_all_properties(sym, prop, P_ENV) {
  838. sym2 = prop_get_symbol(prop);
  839. if (strcmp(sym2->name, env))
  840. menu_warn(current_entry, "redefining environment symbol from %s",
  841. sym2->name);
  842. return;
  843. }
  844. prop = prop_alloc(P_ENV, sym);
  845. prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
  846. sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
  847. sym_env_list->right.sym = sym;
  848. p = getenv(env);
  849. if (p)
  850. sym_add_default(sym, p);
  851. else
  852. menu_warn(current_entry, "environment variable %s undefined", env);
  853. }