symbol.c 18 KB

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