X-Git-Url: https://git.archive.openwrt.org/?p=openwrt.git;a=blobdiff_plain;f=scripts%2Fconfig%2Fmenu.c;fp=scripts%2Fconfig%2Fmenu.c;h=72c9dba84c5dbd46cb8ae2824a85d54603dbaafe;hp=f3bffa309333061ed5d852e7c00132107017add5;hb=2fbbe49c0ac77681c069743e84b711b2a4967dbf;hpb=3c10624a8ee0bd49c213b878c109612d3ad4333e diff --git a/scripts/config/menu.c b/scripts/config/menu.c index f3bffa3093..72c9dba84c 100644 --- a/scripts/config/menu.c +++ b/scripts/config/menu.c @@ -119,9 +119,10 @@ void menu_set_type(int type) sym->type = type; return; } - menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'", - sym->name ? sym->name : "", - sym_type_name(sym->type), sym_type_name(type)); + menu_warn(current_entry, + "ignoring type redefinition of '%s' from '%s' to '%s'", + sym->name ? sym->name : "", + sym_type_name(sym->type), sym_type_name(type)); } struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) @@ -146,11 +147,24 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e struct menu *menu = current_entry; while ((menu = menu->parent) != NULL) { + struct expr *dup_expr; + if (!menu->visibility) continue; + /* + * Do not add a reference to the + * menu's visibility expression but + * use a copy of it. Otherwise the + * expression reduction functions + * will modify expressions that have + * multiple references which can + * cause unwanted side effects. + */ + dup_expr = expr_copy(menu->visibility); + prop->visible.expr = expr_alloc_and(prop->visible.expr, - menu->visibility); + dup_expr); } } @@ -184,12 +198,15 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) void menu_add_option(int token, char *arg) { - struct property *prop; - switch (token) { case T_OPT_MODULES: - prop = prop_alloc(P_DEFAULT, modules_sym); - prop->expr = expr_alloc_symbol(current_entry->sym); + if (modules_sym) + zconf_error("symbol '%s' redefines option 'modules'" + " already defined by symbol '%s'", + current_entry->sym->name, + modules_sym->name + ); + modules_sym = current_entry->sym; break; case T_OPT_DEFCONFIG_LIST: if (!sym_defconfig_list) @@ -200,6 +217,9 @@ void menu_add_option(int token, char *arg) case T_OPT_ENV: prop_add_env(arg); break; + case T_OPT_ALLNOCONFIG_Y: + current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; + break; } } @@ -238,8 +258,8 @@ static void sym_check_prop(struct symbol *sym) "config symbol '%s' uses select, but is " "not boolean or tristate", sym->name); else if (sym2->type != S_UNKNOWN && - sym2->type != S_BOOLEAN && - sym2->type != S_TRISTATE) + sym2->type != S_BOOLEAN && + sym2->type != S_TRISTATE) prop_warn(prop, "'%s' has wrong type. 'select' only " "accept arguments of boolean and " @@ -248,7 +268,7 @@ static void sym_check_prop(struct symbol *sym) case P_RANGE: if (sym->type != S_INT && sym->type != S_HEX) prop_warn(prop, "range is only allowed " - "for int or hex symbols"); + "for int or hex symbols"); if (!menu_validate_number(sym, prop->expr->left.sym) || !menu_validate_number(sym, prop->expr->right.sym)) prop_warn(prop, "range is invalid"); @@ -430,6 +450,22 @@ bool menu_has_prompt(struct menu *menu) return true; } +/* + * Determine if a menu is empty. + * A menu is considered empty if it contains no or only + * invisible entries. + */ +bool menu_is_empty(struct menu *menu) +{ + struct menu *child; + + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child)) + return(false); + } + return(true); +} + bool menu_is_visible(struct menu *menu) { struct menu *child; @@ -512,16 +548,9 @@ static void get_prompt_str(struct gstr *r, struct property *prop, { int i, j; struct menu *submenu[8], *menu, *location = NULL; - struct jump_key *jump; + struct jump_key *jump = NULL; str_printf(r, _("Prompt: %s\n"), _(prop->text)); - str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, - prop->menu->lineno); - if (!expr_is_yes(prop->visible.expr)) { - str_append(r, _(" Depends on: ")); - expr_gstr_print(prop->visible.expr, r); - str_append(r, "\n"); - } menu = prop->menu->parent; for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { bool accessible = menu_is_visible(menu); @@ -557,8 +586,8 @@ static void get_prompt_str(struct gstr *r, struct property *prop, str_printf(r, _(" Location:\n")); for (j = 4; --i >= 0; j += 2) { menu = submenu[i]; - if (head && location && menu == location) - jump->offset = r->len - 1; + if (jump && menu == location) + jump->offset = strlen(r->s); str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); if (menu->sym) { @@ -572,6 +601,18 @@ static void get_prompt_str(struct gstr *r, struct property *prop, } /* + * get property of type P_SYMBOL + */ +static struct property *get_symbol_prop(struct symbol *sym) +{ + struct property *prop = NULL; + + for_all_properties(sym, prop, P_SYMBOL) + break; + return prop; +} + +/* * head is optional and may be NULL */ void get_symbol_str(struct gstr *r, struct symbol *sym, @@ -595,6 +636,18 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, } for_all_prompts(sym, prop) get_prompt_str(r, prop, head); + + prop = get_symbol_prop(sym); + if (prop) { + str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, + prop->menu->lineno); + if (!expr_is_yes(prop->visible.expr)) { + str_append(r, _(" Depends on: ")); + expr_gstr_print(prop->visible.expr, r); + str_append(r, "\n"); + } + } + hit = false; for_all_properties(sym, prop, P_SELECT) { if (!hit) {