-rw-r--r-- | scripts/kconfig/symbol.c | 465 |
1 files changed, 307 insertions, 158 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 845d8a3..11318d9 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -35,16 +35,7 @@ struct symbol *modules_sym; | |||
35 | void sym_add_default(struct symbol *sym, const char *def) | 35 | void sym_add_default(struct symbol *sym, const char *def) |
36 | { | 36 | { |
37 | struct property *prop = create_prop(P_DEFAULT); | 37 | struct property *prop = prop_alloc(P_DEFAULT, sym); |
38 | struct property **propp; | ||
39 | |||
40 | prop->sym = sym; | ||
41 | prop->def = sym_lookup(def, 1); | ||
42 | 38 | ||
43 | /* append property to the prop list of symbol */ | 39 | prop->expr = expr_alloc_symbol(sym_lookup(def, 1)); |
44 | if (prop->sym) { | ||
45 | for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next) | ||
46 | ; | ||
47 | *propp = prop; | ||
48 | } | ||
49 | } | 40 | } |
50 | 41 | ||
@@ -82,7 +73,8 @@ void sym_init(void) | |||
82 | } | 73 | } |
83 | 74 | ||
84 | int sym_get_type(struct symbol *sym) | 75 | enum symbol_type sym_get_type(struct symbol *sym) |
85 | { | 76 | { |
86 | int type = sym->type; | 77 | enum symbol_type type = sym->type; |
78 | |||
87 | if (type == S_TRISTATE) { | 79 | if (type == S_TRISTATE) { |
88 | if (sym_is_choice_value(sym) && sym->visible == yes) | 80 | if (sym_is_choice_value(sym) && sym->visible == yes) |
@@ -90,5 +82,5 @@ int sym_get_type(struct symbol *sym) | |||
90 | else { | 82 | else { |
91 | sym_calc_value(modules_sym); | 83 | sym_calc_value(modules_sym); |
92 | if (S_TRI(modules_sym->curr) == no) | 84 | if (modules_sym->curr.tri == no) |
93 | type = S_BOOLEAN; | 85 | type = S_BOOLEAN; |
94 | } | 86 | } |
@@ -97,5 +89,5 @@ int sym_get_type(struct symbol *sym) | |||
97 | } | 89 | } |
98 | 90 | ||
99 | const char *sym_type_name(int type) | 91 | const char *sym_type_name(enum symbol_type type) |
100 | { | 92 | { |
101 | switch (type) { | 93 | switch (type) { |
@@ -112,4 +104,6 @@ const char *sym_type_name(int type) | |||
112 | case S_UNKNOWN: | 104 | case S_UNKNOWN: |
113 | return "unknown"; | 105 | return "unknown"; |
106 | case S_OTHER: | ||
107 | break; | ||
114 | } | 108 | } |
115 | return "???"; | 109 | return "???"; |
@@ -128,9 +122,8 @@ struct property *sym_get_default_prop(struct symbol *sym) | |||
128 | { | 122 | { |
129 | struct property *prop; | 123 | struct property *prop; |
130 | tristate visible; | ||
131 | 124 | ||
132 | for_all_defaults(sym, prop) { | 125 | for_all_defaults(sym, prop) { |
133 | visible = E_CALC(prop->visible); | 126 | prop->visible.tri = expr_calc_value(prop->visible.expr); |
134 | if (visible != no) | 127 | if (prop->visible.tri != no) |
135 | return prop; | 128 | return prop; |
136 | } | 129 | } |
@@ -138,29 +131,93 @@ struct property *sym_get_default_prop(struct symbol *sym) | |||
138 | } | 131 | } |
139 | 132 | ||
140 | void sym_calc_visibility(struct symbol *sym) | 133 | struct property *sym_get_range_prop(struct symbol *sym) |
141 | { | 134 | { |
142 | struct property *prop; | 135 | struct property *prop; |
143 | tristate visible, oldvisible; | 136 | |
137 | for_all_properties(sym, prop, P_RANGE) { | ||
138 | prop->visible.tri = expr_calc_value(prop->visible.expr); | ||
139 | if (prop->visible.tri != no) | ||
140 | return prop; | ||
141 | } | ||
142 | return NULL; | ||
143 | } | ||
144 | |||
145 | static void sym_calc_visibility(struct symbol *sym) | ||
146 | { | ||
147 | struct property *prop; | ||
148 | tristate tri; | ||
144 | 149 | ||
145 | /* any prompt visible? */ | 150 | /* any prompt visible? */ |
146 | oldvisible = sym->visible; | 151 | tri = no; |
147 | visible = no; | 152 | for_all_prompts(sym, prop) { |
148 | for_all_prompts(sym, prop) | 153 | prop->visible.tri = expr_calc_value(prop->visible.expr); |
149 | visible = E_OR(visible, E_CALC(prop->visible)); | 154 | tri = E_OR(tri, prop->visible.tri); |
150 | if (oldvisible != visible) { | 155 | } |
151 | sym->visible = visible; | 156 | if (sym->visible != tri) { |
157 | sym->visible = tri; | ||
158 | sym_set_changed(sym); | ||
159 | } | ||
160 | if (sym_is_choice_value(sym)) | ||
161 | return; | ||
162 | tri = no; | ||
163 | if (sym->rev_dep.expr) | ||
164 | tri = expr_calc_value(sym->rev_dep.expr); | ||
165 | if (sym->rev_dep.tri != tri) { | ||
166 | sym->rev_dep.tri = tri; | ||
152 | sym_set_changed(sym); | 167 | sym_set_changed(sym); |
153 | } | 168 | } |
154 | } | 169 | } |
155 | 170 | ||
171 | static struct symbol *sym_calc_choice(struct symbol *sym) | ||
172 | { | ||
173 | struct symbol *def_sym; | ||
174 | struct property *prop; | ||
175 | struct expr *e; | ||
176 | |||
177 | /* is the user choice visible? */ | ||
178 | def_sym = sym->user.val; | ||
179 | if (def_sym) { | ||
180 | sym_calc_visibility(def_sym); | ||
181 | if (def_sym->visible != no) | ||
182 | return def_sym; | ||
183 | } | ||
184 | |||
185 | /* any of the defaults visible? */ | ||
186 | for_all_defaults(sym, prop) { | ||
187 | prop->visible.tri = expr_calc_value(prop->visible.expr); | ||
188 | if (prop->visible.tri == no) | ||
189 | continue; | ||
190 | def_sym = prop_get_symbol(prop); | ||
191 | sym_calc_visibility(def_sym); | ||
192 | if (def_sym->visible != no) | ||
193 | return def_sym; | ||
194 | } | ||
195 | |||
196 | /* just get the first visible value */ | ||
197 | prop = sym_get_choice_prop(sym); | ||
198 | for (e = prop->expr; e; e = e->left.expr) { | ||
199 | def_sym = e->right.sym; | ||
200 | sym_calc_visibility(def_sym); | ||
201 | if (def_sym->visible != no) | ||
202 | return def_sym; | ||
203 | } | ||
204 | |||
205 | /* no choice? reset tristate value */ | ||
206 | sym->curr.tri = no; | ||
207 | return NULL; | ||
208 | } | ||
209 | |||
156 | void sym_calc_value(struct symbol *sym) | 210 | void sym_calc_value(struct symbol *sym) |
157 | { | 211 | { |
158 | struct symbol_value newval, oldval; | 212 | struct symbol_value newval, oldval; |
159 | struct property *prop, *def_prop; | 213 | struct property *prop; |
160 | struct symbol *def_sym; | ||
161 | struct expr *e; | 214 | struct expr *e; |
162 | 215 | ||
216 | if (!sym) | ||
217 | return; | ||
218 | |||
163 | if (sym->flags & SYMBOL_VALID) | 219 | if (sym->flags & SYMBOL_VALID) |
164 | return; | 220 | return; |
221 | sym->flags |= SYMBOL_VALID; | ||
165 | 222 | ||
166 | oldval = sym->curr; | 223 | oldval = sym->curr; |
@@ -177,15 +234,8 @@ void sym_calc_value(struct symbol *sym) | |||
177 | break; | 234 | break; |
178 | default: | 235 | default: |
179 | S_VAL(newval) = sym->name; | 236 | sym->curr.val = sym->name; |
180 | S_TRI(newval) = no; | 237 | sym->curr.tri = no; |
181 | if (sym->flags & SYMBOL_CONST) { | 238 | return; |
182 | goto out; | ||
183 | } | ||
184 | //newval = symbol_empty.curr; | ||
185 | // generate warning somewhere here later | ||
186 | //S_TRI(newval) = yes; | ||
187 | goto out; | ||
188 | } | 239 | } |
189 | sym->flags |= SYMBOL_VALID; | ||
190 | if (!sym_is_choice_value(sym)) | 240 | if (!sym_is_choice_value(sym)) |
191 | sym->flags &= ~SYMBOL_WRITE; | 241 | sym->flags &= ~SYMBOL_WRITE; |
@@ -196,93 +246,71 @@ void sym_calc_value(struct symbol *sym) | |||
196 | sym->curr = newval; | 246 | sym->curr = newval; |
197 | 247 | ||
198 | if (sym->visible != no) { | 248 | switch (sym_get_type(sym)) { |
199 | sym->flags |= SYMBOL_WRITE; | 249 | case S_BOOLEAN: |
200 | if (!sym_has_value(sym)) { | 250 | case S_TRISTATE: |
201 | if (!sym_is_choice(sym)) { | ||
202 | prop = sym_get_default_prop(sym); | ||
203 | if (prop) { | ||
204 | sym_calc_value(prop->def); | ||
205 | newval = prop->def->curr; | ||
206 | } | ||
207 | } else | ||
208 | S_TRI(newval) = S_TRI(sym->def); | ||
209 | } else | ||
210 | newval = sym->def; | ||
211 | |||
212 | S_TRI(newval) = E_AND(S_TRI(newval), sym->visible); | ||
213 | /* if the symbol is visible and not optionial, | ||
214 | * possibly ignore old user choice. */ | ||
215 | if (!sym_is_optional(sym) && S_TRI(newval) == no) | ||
216 | S_TRI(newval) = sym->visible; | ||
217 | if (sym_is_choice_value(sym) && sym->visible == yes) { | 251 | if (sym_is_choice_value(sym) && sym->visible == yes) { |
218 | prop = sym_get_choice_prop(sym); | 252 | prop = sym_get_choice_prop(sym); |
219 | S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no; | 253 | newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; |
220 | } | 254 | } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) { |
221 | } else { | ||
222 | prop = sym_get_default_prop(sym); | ||
223 | if (prop) { | ||
224 | sym->flags |= SYMBOL_WRITE; | 255 | sym->flags |= SYMBOL_WRITE; |
225 | sym_calc_value(prop->def); | 256 | if (sym_has_value(sym)) |
226 | newval = prop->def->curr; | 257 | newval.tri = sym->user.tri; |
258 | else if (!sym_is_choice(sym)) { | ||
259 | prop = sym_get_default_prop(sym); | ||
260 | if (prop) | ||
261 | newval.tri = expr_calc_value(prop->expr); | ||
262 | } | ||
263 | newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri); | ||
264 | } else if (!sym_is_choice(sym)) { | ||
265 | prop = sym_get_default_prop(sym); | ||
266 | if (prop) { | ||
267 | sym->flags |= SYMBOL_WRITE; | ||
268 | newval.tri = expr_calc_value(prop->expr); | ||
269 | } | ||
227 | } | 270 | } |
228 | } | 271 | if (sym_get_type(sym) == S_BOOLEAN) { |
229 | 272 | if (newval.tri == mod) | |
230 | switch (sym_get_type(sym)) { | 273 | newval.tri = yes; |
231 | case S_TRISTATE: | 274 | if (sym->visible == mod) |
232 | if (S_TRI(newval) != mod) | 275 | sym->visible = yes; |
233 | break; | 276 | if (sym->rev_dep.tri == mod) |
234 | sym_calc_value(modules_sym); | 277 | sym->rev_dep.tri = yes; |
235 | if (S_TRI(modules_sym->curr) == no) | ||
236 | S_TRI(newval) = yes; | ||
237 | break; | ||
238 | case S_BOOLEAN: | ||
239 | if (S_TRI(newval) == mod) | ||
240 | S_TRI(newval) = yes; | ||
241 | } | ||
242 | |||
243 | out: | ||
244 | sym->curr = newval; | ||
245 | |||
246 | if (sym_is_choice(sym) && S_TRI(newval) == yes) { | ||
247 | def_sym = S_VAL(sym->def); | ||
248 | if (def_sym) { | ||
249 | sym_calc_visibility(def_sym); | ||
250 | if (def_sym->visible == no) | ||
251 | def_sym = NULL; | ||
252 | } | 278 | } |
253 | if (!def_sym) { | 279 | break; |
254 | for_all_defaults(sym, def_prop) { | 280 | case S_STRING: |
255 | if (E_CALC(def_prop->visible) == no) | 281 | case S_HEX: |
256 | continue; | 282 | case S_INT: |
257 | sym_calc_visibility(def_prop->def); | 283 | if (sym->visible != no) { |
258 | if (def_prop->def->visible != no) { | 284 | sym->flags |= SYMBOL_WRITE; |
259 | def_sym = def_prop->def; | 285 | if (sym_has_value(sym)) { |
260 | break; | 286 | newval.val = sym->user.val; |
261 | } | 287 | break; |
262 | } | 288 | } |
263 | } | 289 | } |
264 | 290 | prop = sym_get_default_prop(sym); | |
265 | if (!def_sym) { | 291 | if (prop) { |
266 | prop = sym_get_choice_prop(sym); | 292 | struct symbol *ds = prop_get_symbol(prop); |
267 | for (e = prop->dep; e; e = e->left.expr) { | 293 | if (ds) { |
268 | sym_calc_visibility(e->right.sym); | 294 | sym->flags |= SYMBOL_WRITE; |
269 | if (e->right.sym->visible != no) { | 295 | sym_calc_value(ds); |
270 | def_sym = e->right.sym; | 296 | newval.val = ds->curr.val; |
271 | break; | ||
272 | } | ||
273 | } | 297 | } |
274 | } | 298 | } |
275 | 299 | break; | |
276 | S_VAL(newval) = def_sym; | 300 | default: |
301 | ; | ||
277 | } | 302 | } |
278 | 303 | ||
279 | if (memcmp(&oldval, &newval, sizeof(newval))) | ||
280 | sym_set_changed(sym); | ||
281 | sym->curr = newval; | 304 | sym->curr = newval; |
305 | if (sym_is_choice(sym) && newval.tri == yes) | ||
306 | sym->curr.val = sym_calc_choice(sym); | ||
307 | |||
308 | if (memcmp(&oldval, &sym->curr, sizeof(oldval))) | ||
309 | sym_set_changed(sym); | ||
282 | 310 | ||
283 | if (sym_is_choice(sym)) { | 311 | if (sym_is_choice(sym)) { |
284 | int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); | 312 | int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); |
285 | prop = sym_get_choice_prop(sym); | 313 | prop = sym_get_choice_prop(sym); |
286 | for (e = prop->dep; e; e = e->left.expr) { | 314 | for (e = prop->expr; e; e = e->left.expr) { |
287 | e->right.sym->flags |= flags; | 315 | e->right.sym->flags |= flags; |
288 | if (flags & SYMBOL_CHANGED) | 316 | if (flags & SYMBOL_CHANGED) |
@@ -332,17 +360,11 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) | |||
332 | return false; | 360 | return false; |
333 | 361 | ||
334 | switch (val) { | 362 | if (type == S_BOOLEAN && val == mod) |
335 | case no: | 363 | return false; |
336 | if (sym_is_choice_value(sym) && sym->visible == yes) | 364 | if (sym->visible <= sym->rev_dep.tri) |
337 | return false; | 365 | return false; |
338 | return sym_is_optional(sym); | 366 | if (sym_is_choice_value(sym) && sym->visible == yes) |
339 | case mod: | 367 | return val == yes; |
340 | if (sym_is_choice_value(sym) && sym->visible == yes) | 368 | return val >= sym->rev_dep.tri && val <= sym->visible; |
341 | return false; | ||
342 | return type == S_TRISTATE; | ||
343 | case yes: | ||
344 | return type == S_BOOLEAN || sym->visible == yes; | ||
345 | } | ||
346 | return false; | ||
347 | } | 369 | } |
348 | 370 | ||
@@ -359,11 +381,11 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) | |||
359 | } | 381 | } |
360 | if (sym_is_choice_value(sym) && val == yes) { | 382 | if (sym_is_choice_value(sym) && val == yes) { |
361 | struct property *prop = sym_get_choice_prop(sym); | 383 | struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); |
362 | 384 | ||
363 | S_VAL(prop->def->def) = sym; | 385 | cs->user.val = sym; |
364 | prop->def->flags &= ~SYMBOL_NEW; | 386 | cs->flags &= ~SYMBOL_NEW; |
365 | } | 387 | } |
366 | 388 | ||
367 | S_TRI(sym->def) = val; | 389 | sym->user.tri = val; |
368 | if (oldval != val) { | 390 | if (oldval != val) { |
369 | sym_clear_all_valid(); | 391 | sym_clear_all_valid(); |
@@ -430,12 +452,49 @@ bool sym_string_valid(struct symbol *sym, const char *str) | |||
430 | case S_TRISTATE: | 452 | case S_TRISTATE: |
431 | switch (str[0]) { | 453 | switch (str[0]) { |
432 | case 'y': | 454 | case 'y': case 'Y': |
433 | case 'Y': | 455 | case 'm': case 'M': |
456 | case 'n': case 'N': | ||
457 | return true; | ||
458 | } | ||
459 | return false; | ||
460 | default: | ||
461 | return false; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | bool sym_string_within_range(struct symbol *sym, const char *str) | ||
466 | { | ||
467 | struct property *prop; | ||
468 | int val; | ||
469 | |||
470 | switch (sym->type) { | ||
471 | case S_STRING: | ||
472 | return sym_string_valid(sym, str); | ||
473 | case S_INT: | ||
474 | if (!sym_string_valid(sym, str)) | ||
475 | return false; | ||
476 | prop = sym_get_range_prop(sym); | ||
477 | if (!prop) | ||
478 | return true; | ||
479 | val = strtol(str, NULL, 10); | ||
480 | return val >= strtol(prop->expr->left.sym->name, NULL, 10) && | ||
481 | val <= strtol(prop->expr->right.sym->name, NULL, 10); | ||
482 | case S_HEX: | ||
483 | if (!sym_string_valid(sym, str)) | ||
484 | return false; | ||
485 | prop = sym_get_range_prop(sym); | ||
486 | if (!prop) | ||
487 | return true; | ||
488 | val = strtol(str, NULL, 16); | ||
489 | return val >= strtol(prop->expr->left.sym->name, NULL, 16) && | ||
490 | val <= strtol(prop->expr->right.sym->name, NULL, 16); | ||
491 | case S_BOOLEAN: | ||
492 | case S_TRISTATE: | ||
493 | switch (str[0]) { | ||
494 | case 'y': case 'Y': | ||
434 | return sym_tristate_within_range(sym, yes); | 495 | return sym_tristate_within_range(sym, yes); |
435 | case 'm': | 496 | case 'm': case 'M': |
436 | case 'M': | ||
437 | return sym_tristate_within_range(sym, mod); | 497 | return sym_tristate_within_range(sym, mod); |
438 | case 'n': | 498 | case 'n': case 'N': |
439 | case 'N': | ||
440 | return sym_tristate_within_range(sym, no); | 499 | return sym_tristate_within_range(sym, no); |
441 | } | 500 | } |
@@ -456,12 +515,9 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) | |||
456 | case S_TRISTATE: | 515 | case S_TRISTATE: |
457 | switch (newval[0]) { | 516 | switch (newval[0]) { |
458 | case 'y': | 517 | case 'y': case 'Y': |
459 | case 'Y': | ||
460 | return sym_set_tristate_value(sym, yes); | 518 | return sym_set_tristate_value(sym, yes); |
461 | case 'm': | 519 | case 'm': case 'M': |
462 | case 'M': | ||
463 | return sym_set_tristate_value(sym, mod); | 520 | return sym_set_tristate_value(sym, mod); |
464 | case 'n': | 521 | case 'n': case 'N': |
465 | case 'N': | ||
466 | return sym_set_tristate_value(sym, no); | 522 | return sym_set_tristate_value(sym, no); |
467 | } | 523 | } |
@@ -471,5 +527,5 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) | |||
471 | } | 527 | } |
472 | 528 | ||
473 | if (!sym_string_valid(sym, newval)) | 529 | if (!sym_string_within_range(sym, newval)) |
474 | return false; | 530 | return false; |
475 | 531 | ||
@@ -479,13 +535,13 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) | |||
479 | } | 535 | } |
480 | 536 | ||
481 | oldval = S_VAL(sym->def); | 537 | oldval = sym->user.val; |
482 | size = strlen(newval) + 1; | 538 | size = strlen(newval) + 1; |
483 | if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { | 539 | if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { |
484 | size += 2; | 540 | size += 2; |
485 | S_VAL(sym->def) = val = malloc(size); | 541 | sym->user.val = val = malloc(size); |
486 | *val++ = '0'; | 542 | *val++ = '0'; |
487 | *val++ = 'x'; | 543 | *val++ = 'x'; |
488 | } else if (!oldval || strcmp(oldval, newval)) | 544 | } else if (!oldval || strcmp(oldval, newval)) |
489 | S_VAL(sym->def) = val = malloc(size); | 545 | sym->user.val = val = malloc(size); |
490 | else | 546 | else |
491 | return true; | 547 | return true; |
@@ -518,18 +574,10 @@ const char *sym_get_string_value(struct symbol *sym) | |||
518 | ; | 574 | ; |
519 | } | 575 | } |
520 | return (const char *)S_VAL(sym->curr); | 576 | return (const char *)sym->curr.val; |
521 | } | 577 | } |
522 | 578 | ||
523 | bool sym_is_changable(struct symbol *sym) | 579 | bool sym_is_changable(struct symbol *sym) |
524 | { | 580 | { |
525 | if (sym->visible == no) | 581 | return sym->visible > sym->rev_dep.tri; |
526 | return false; | ||
527 | /* at least 'n' and 'y'/'m' is selectable */ | ||
528 | if (sym_is_optional(sym)) | ||
529 | return true; | ||
530 | /* no 'n', so 'y' and 'm' must be selectable */ | ||
531 | if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes) | ||
532 | return true; | ||
533 | return false; | ||
534 | } | 582 | } |
535 | 583 | ||
@@ -609,4 +657,102 @@ struct symbol *sym_find(const char *name) | |||
609 | } | 657 | } |
610 | 658 | ||
659 | struct symbol *sym_check_deps(struct symbol *sym); | ||
660 | |||
661 | static struct symbol *sym_check_expr_deps(struct expr *e) | ||
662 | { | ||
663 | struct symbol *sym; | ||
664 | |||
665 | if (!e) | ||
666 | return NULL; | ||
667 | switch (e->type) { | ||
668 | case E_OR: | ||
669 | case E_AND: | ||
670 | sym = sym_check_expr_deps(e->left.expr); | ||
671 | if (sym) | ||
672 | return sym; | ||
673 | return sym_check_expr_deps(e->right.expr); | ||
674 | case E_NOT: | ||
675 | return sym_check_expr_deps(e->left.expr); | ||
676 | case E_EQUAL: | ||
677 | case E_UNEQUAL: | ||
678 | sym = sym_check_deps(e->left.sym); | ||
679 | if (sym) | ||
680 | return sym; | ||
681 | return sym_check_deps(e->right.sym); | ||
682 | case E_SYMBOL: | ||
683 | return sym_check_deps(e->left.sym); | ||
684 | default: | ||
685 | break; | ||
686 | } | ||
687 | printf("Oops! How to check %d?\n", e->type); | ||
688 | return NULL; | ||
689 | } | ||
690 | |||
691 | struct symbol *sym_check_deps(struct symbol *sym) | ||
692 | { | ||
693 | struct symbol *sym2; | ||
694 | struct property *prop; | ||
695 | |||
696 | if (sym->flags & SYMBOL_CHECK_DONE) | ||
697 | return NULL; | ||
698 | if (sym->flags & SYMBOL_CHECK) { | ||
699 | printf("Warning! Found recursive dependency: %s", sym->name); | ||
700 | return sym; | ||
701 | } | ||
702 | |||
703 | sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); | ||
704 | sym2 = sym_check_expr_deps(sym->rev_dep.expr); | ||
705 | if (sym2) | ||
706 | goto out; | ||
707 | |||
708 | for (prop = sym->prop; prop; prop = prop->next) { | ||
709 | if (prop->type == P_CHOICE) | ||
710 | continue; | ||
711 | sym2 = sym_check_expr_deps(prop->visible.expr); | ||
712 | if (sym2) | ||
713 | goto out; | ||
714 | if (prop->type != P_DEFAULT || sym_is_choice(sym)) | ||
715 | continue; | ||
716 | sym2 = sym_check_expr_deps(prop->expr); | ||
717 | if (sym2) | ||
718 | goto out; | ||
719 | } | ||
720 | out: | ||
721 | if (sym2) | ||
722 | printf(" %s", sym->name); | ||
723 | sym->flags &= ~SYMBOL_CHECK; | ||
724 | return sym2; | ||
725 | } | ||
726 | |||
727 | struct property *prop_alloc(enum prop_type type, struct symbol *sym) | ||
728 | { | ||
729 | struct property *prop; | ||
730 | struct property **propp; | ||
731 | |||
732 | prop = malloc(sizeof(*prop)); | ||
733 | memset(prop, 0, sizeof(*prop)); | ||
734 | prop->type = type; | ||
735 | prop->sym = sym; | ||
736 | prop->file = current_file; | ||
737 | prop->lineno = zconf_lineno(); | ||
738 | |||
739 | /* append property to the prop list of symbol */ | ||
740 | if (sym) { | ||
741 | for (propp = &sym->prop; *propp; propp = &(*propp)->next) | ||
742 | ; | ||
743 | *propp = prop; | ||
744 | } | ||
745 | |||
746 | return prop; | ||
747 | } | ||
748 | |||
749 | struct symbol *prop_get_symbol(struct property *prop) | ||
750 | { | ||
751 | if (prop->expr && (prop->expr->type == E_SYMBOL || | ||
752 | prop->expr->type == E_CHOICE)) | ||
753 | return prop->expr->left.sym; | ||
754 | return NULL; | ||
755 | } | ||
756 | |||
611 | const char *prop_get_type_name(enum prop_type type) | 757 | const char *prop_get_type_name(enum prop_type type) |
612 | { | 758 | { |
@@ -618,12 +764,15 @@ const char *prop_get_type_name(enum prop_type type) | |||
618 | case P_MENU: | 764 | case P_MENU: |
619 | return "menu"; | 765 | return "menu"; |
620 | case P_ROOTMENU: | ||
621 | return "rootmenu"; | ||
622 | case P_DEFAULT: | 766 | case P_DEFAULT: |
623 | return "default"; | 767 | return "default"; |
624 | case P_CHOICE: | 768 | case P_CHOICE: |
625 | return "choice"; | 769 | return "choice"; |
626 | default: | 770 | case P_SELECT: |
627 | return "unknown"; | 771 | return "select"; |
772 | case P_RANGE: | ||
773 | return "range"; | ||
774 | case P_UNKNOWN: | ||
775 | break; | ||
628 | } | 776 | } |
777 | return "unknown"; | ||
629 | } | 778 | } |