symbol.c 17 KB

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