symbol.c 16 KB

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