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 @@
#include "lkc.h"
static const char nohelp_text[] = N_(
- "There is no help available for this kernel option.\n");
+ "There is no help available for this option.\n");
struct menu rootmenu;
static struct menu **last_entry_ptr;
@@ -58,6 +58,8 @@ void menu_add_entry(struct symbol *sym)
*last_entry_ptr = menu;
last_entry_ptr = &menu->next;
current_entry = menu;
+ if (sym)
+ menu_add_symbol(P_SYMBOL, sym, NULL);
}
void menu_end_entry(void)
@@ -136,8 +138,22 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
while (isspace(*prompt))
prompt++;
}
- if (current_entry->prompt)
+ if (current_entry->prompt && current_entry != &rootmenu)
prop_warn(prop, "prompt redefined");
+
+ /* Apply all upper menus' visibilities to actual prompts. */
+ if(type == P_PROMPT) {
+ struct menu *menu = current_entry;
+
+ while ((menu = menu->parent) != NULL) {
+ if (!menu->visibility)
+ continue;
+ prop->visible.expr
+ = expr_alloc_and(prop->visible.expr,
+ menu->visibility);
+ }
+ }
+
current_entry->prompt = prop;
}
prop->text = prompt;
@@ -150,6 +166,12 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr
return menu_add_prop(type, prompt, NULL, dep);
}
+void menu_add_visibility(struct expr *expr)
+{
+ current_entry->visibility = expr_alloc_and(current_entry->visibility,
+ expr);
+}
+
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
{
menu_add_prop(type, NULL, expr, dep);
@@ -181,7 +203,7 @@ void menu_add_option(int token, char *arg)
}
}
-static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
+static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
{
return sym2->type == S_INT || sym2->type == S_HEX ||
(sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
@@ -199,6 +221,15 @@ static void sym_check_prop(struct symbol *sym)
prop_warn(prop,
"default for config symbol '%s'"
" must be a single symbol", sym->name);
+ if (prop->expr->type != E_SYMBOL)
+ break;
+ sym2 = prop_get_symbol(prop);
+ if (sym->type == S_HEX || sym->type == S_INT) {
+ if (!menu_validate_number(sym, sym2))
+ prop_warn(prop,
+ "'%s': number is invalid",
+ sym->name);
+ }
break;
case P_SELECT:
sym2 = prop_get_symbol(prop);
@@ -218,8 +249,8 @@ static void sym_check_prop(struct symbol *sym)
if (sym->type != S_INT && sym->type != S_HEX)
prop_warn(prop, "range is only allowed "
"for int or hex symbols");
- if (!menu_range_valid_sym(sym, prop->expr->left.sym) ||
- !menu_range_valid_sym(sym, prop->expr->right.sym))
+ if (!menu_validate_number(sym, prop->expr->left.sym) ||
+ !menu_validate_number(sym, prop->expr->right.sym))
prop_warn(prop, "range is invalid");
break;
default:
@@ -318,6 +349,8 @@ void menu_finalize(struct menu *parent)
parent->next = last_menu->next;
last_menu->next = NULL;
}
+
+ sym->dir_dep.expr = parent->dep;
}
for (menu = parent->list; menu; menu = menu->next) {
if (sym && sym_is_choice(sym) &&
@@ -406,6 +439,11 @@ bool menu_is_visible(struct menu *menu)
if (!menu->prompt)
return false;
+ if (menu->visibility) {
+ if (expr_calc_value(menu->visibility) == no)
+ return no;
+ }
+
sym = menu->sym;
if (sym) {
sym_calc_value(sym);
@@ -419,9 +457,13 @@ bool menu_is_visible(struct menu *menu)
if (!sym || sym_get_tristate_value(menu->sym) == no)
return false;
- for (child = menu->list; child; child = child->next)
- if (menu_is_visible(child))
+ for (child = menu->list; child; child = child->next) {
+ if (menu_is_visible(child)) {
+ if (sym)
+ sym->flags |= SYMBOL_DEF_USER;
return true;
+ }
+ }
return false;
}
@@ -501,9 +543,19 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
bool hit;
struct property *prop;
- if (sym && sym->name)
+ if (sym && sym->name) {
str_printf(r, "Symbol: %s [=%s]\n", sym->name,
sym_get_string_value(sym));
+ str_printf(r, "Type : %s\n", sym_type_name(sym->type));
+ if (sym->type == S_INT || sym->type == S_HEX) {
+ prop = sym_get_range_prop(sym);
+ if (prop) {
+ str_printf(r, "Range : ");
+ expr_gstr_print(prop->expr, r);
+ str_append(r, "\n");
+ }
+ }
+ }
for_all_prompts(sym, prop)
get_prompt_str(r, prop);
hit = false;
@@ -545,7 +597,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
if (menu_has_help(menu)) {
if (sym->name) {
- str_printf(help, "CONFIG_%s:\n\n", sym->name);
+ str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
str_append(help, _(menu_get_help(menu)));
str_append(help, "\n");
}