aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kconfig/menu.c')
-rw-r--r--scripts/kconfig/menu.c70
1 files changed, 61 insertions, 9 deletions
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 203632cc30bd..5fdf10dc1d8a 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -10,7 +10,7 @@
10#include "lkc.h" 10#include "lkc.h"
11 11
12static const char nohelp_text[] = N_( 12static const char nohelp_text[] = N_(
13 "There is no help available for this kernel option.\n"); 13 "There is no help available for this option.\n");
14 14
15struct menu rootmenu; 15struct menu rootmenu;
16static struct menu **last_entry_ptr; 16static struct menu **last_entry_ptr;
@@ -58,6 +58,8 @@ void menu_add_entry(struct symbol *sym)
58 *last_entry_ptr = menu; 58 *last_entry_ptr = menu;
59 last_entry_ptr = &menu->next; 59 last_entry_ptr = &menu->next;
60 current_entry = menu; 60 current_entry = menu;
61 if (sym)
62 menu_add_symbol(P_SYMBOL, sym, NULL);
61} 63}
62 64
63void menu_end_entry(void) 65void menu_end_entry(void)
@@ -136,8 +138,22 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
136 while (isspace(*prompt)) 138 while (isspace(*prompt))
137 prompt++; 139 prompt++;
138 } 140 }
139 if (current_entry->prompt) 141 if (current_entry->prompt && current_entry != &rootmenu)
140 prop_warn(prop, "prompt redefined"); 142 prop_warn(prop, "prompt redefined");
143
144 /* Apply all upper menus' visibilities to actual prompts. */
145 if(type == P_PROMPT) {
146 struct menu *menu = current_entry;
147
148 while ((menu = menu->parent) != NULL) {
149 if (!menu->visibility)
150 continue;
151 prop->visible.expr
152 = expr_alloc_and(prop->visible.expr,
153 menu->visibility);
154 }
155 }
156
141 current_entry->prompt = prop; 157 current_entry->prompt = prop;
142 } 158 }
143 prop->text = prompt; 159 prop->text = prompt;
@@ -150,6 +166,12 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr
150 return menu_add_prop(type, prompt, NULL, dep); 166 return menu_add_prop(type, prompt, NULL, dep);
151} 167}
152 168
169void menu_add_visibility(struct expr *expr)
170{
171 current_entry->visibility = expr_alloc_and(current_entry->visibility,
172 expr);
173}
174
153void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) 175void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
154{ 176{
155 menu_add_prop(type, NULL, expr, dep); 177 menu_add_prop(type, NULL, expr, dep);
@@ -181,7 +203,7 @@ void menu_add_option(int token, char *arg)
181 } 203 }
182} 204}
183 205
184static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) 206static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
185{ 207{
186 return sym2->type == S_INT || sym2->type == S_HEX || 208 return sym2->type == S_INT || sym2->type == S_HEX ||
187 (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); 209 (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
@@ -199,6 +221,15 @@ static void sym_check_prop(struct symbol *sym)
199 prop_warn(prop, 221 prop_warn(prop,
200 "default for config symbol '%s'" 222 "default for config symbol '%s'"
201 " must be a single symbol", sym->name); 223 " must be a single symbol", sym->name);
224 if (prop->expr->type != E_SYMBOL)
225 break;
226 sym2 = prop_get_symbol(prop);
227 if (sym->type == S_HEX || sym->type == S_INT) {
228 if (!menu_validate_number(sym, sym2))
229 prop_warn(prop,
230 "'%s': number is invalid",
231 sym->name);
232 }
202 break; 233 break;
203 case P_SELECT: 234 case P_SELECT:
204 sym2 = prop_get_symbol(prop); 235 sym2 = prop_get_symbol(prop);
@@ -218,8 +249,8 @@ static void sym_check_prop(struct symbol *sym)
218 if (sym->type != S_INT && sym->type != S_HEX) 249 if (sym->type != S_INT && sym->type != S_HEX)
219 prop_warn(prop, "range is only allowed " 250 prop_warn(prop, "range is only allowed "
220 "for int or hex symbols"); 251 "for int or hex symbols");
221 if (!menu_range_valid_sym(sym, prop->expr->left.sym) || 252 if (!menu_validate_number(sym, prop->expr->left.sym) ||
222 !menu_range_valid_sym(sym, prop->expr->right.sym)) 253 !menu_validate_number(sym, prop->expr->right.sym))
223 prop_warn(prop, "range is invalid"); 254 prop_warn(prop, "range is invalid");
224 break; 255 break;
225 default: 256 default:
@@ -318,6 +349,8 @@ void menu_finalize(struct menu *parent)
318 parent->next = last_menu->next; 349 parent->next = last_menu->next;
319 last_menu->next = NULL; 350 last_menu->next = NULL;
320 } 351 }
352
353 sym->dir_dep.expr = parent->dep;
321 } 354 }
322 for (menu = parent->list; menu; menu = menu->next) { 355 for (menu = parent->list; menu; menu = menu->next) {
323 if (sym && sym_is_choice(sym) && 356 if (sym && sym_is_choice(sym) &&
@@ -406,6 +439,11 @@ bool menu_is_visible(struct menu *menu)
406 if (!menu->prompt) 439 if (!menu->prompt)
407 return false; 440 return false;
408 441
442 if (menu->visibility) {
443 if (expr_calc_value(menu->visibility) == no)
444 return no;
445 }
446
409 sym = menu->sym; 447 sym = menu->sym;
410 if (sym) { 448 if (sym) {
411 sym_calc_value(sym); 449 sym_calc_value(sym);
@@ -419,9 +457,13 @@ bool menu_is_visible(struct menu *menu)
419 if (!sym || sym_get_tristate_value(menu->sym) == no) 457 if (!sym || sym_get_tristate_value(menu->sym) == no)
420 return false; 458 return false;
421 459
422 for (child = menu->list; child; child = child->next) 460 for (child = menu->list; child; child = child->next) {
423 if (menu_is_visible(child)) 461 if (menu_is_visible(child)) {
462 if (sym)
463 sym->flags |= SYMBOL_DEF_USER;
424 return true; 464 return true;
465 }
466 }
425 467
426 return false; 468 return false;
427} 469}
@@ -501,9 +543,19 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
501 bool hit; 543 bool hit;
502 struct property *prop; 544 struct property *prop;
503 545
504 if (sym && sym->name) 546 if (sym && sym->name) {
505 str_printf(r, "Symbol: %s [=%s]\n", sym->name, 547 str_printf(r, "Symbol: %s [=%s]\n", sym->name,
506 sym_get_string_value(sym)); 548 sym_get_string_value(sym));
549 str_printf(r, "Type : %s\n", sym_type_name(sym->type));
550 if (sym->type == S_INT || sym->type == S_HEX) {
551 prop = sym_get_range_prop(sym);
552 if (prop) {
553 str_printf(r, "Range : ");
554 expr_gstr_print(prop->expr, r);
555 str_append(r, "\n");
556 }
557 }
558 }
507 for_all_prompts(sym, prop) 559 for_all_prompts(sym, prop)
508 get_prompt_str(r, prop); 560 get_prompt_str(r, prop);
509 hit = false; 561 hit = false;
@@ -545,7 +597,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
545 597
546 if (menu_has_help(menu)) { 598 if (menu_has_help(menu)) {
547 if (sym->name) { 599 if (sym->name) {
548 str_printf(help, "CONFIG_%s:\n\n", sym->name); 600 str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
549 str_append(help, _(menu_get_help(menu))); 601 str_append(help, _(menu_get_help(menu)));
550 str_append(help, "\n"); 602 str_append(help, "\n");
551 } 603 }