X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=config%2Fmenu.c;h=a5fbd6ccc006e05308f0ef24cf3cb1545a55cb15;hb=HEAD;hp=379a119dcd1e47bfbf69c9273129ce3859883d08;hpb=bd5e9f6c34b6396318f6214c60cc827290830e5f;p=carl9170fw.git diff --git a/config/menu.c b/config/menu.c index 379a119..a5fbd6c 100644 --- a/config/menu.c +++ b/config/menu.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. */ #include @@ -65,7 +65,8 @@ void menu_add_entry(struct symbol *sym) struct menu *menu_add_menu(void) { last_entry_ptr = ¤t_entry->list; - return current_menu = current_entry; + current_menu = current_entry; + return current_menu; } void menu_end_menu(void) @@ -124,61 +125,76 @@ void menu_set_type(int type) sym_type_name(sym->type), sym_type_name(type)); } -static struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) +static struct property *menu_add_prop(enum prop_type type, struct expr *expr, + struct expr *dep) { - struct property *prop = prop_alloc(type, current_entry->sym); + struct property *prop; + prop = xmalloc(sizeof(*prop)); + memset(prop, 0, sizeof(*prop)); + prop->type = type; + prop->file = current_file; + prop->lineno = zconf_lineno(); prop->menu = current_entry; prop->expr = expr; prop->visible.expr = dep; - if (prompt) { - if (isspace(*prompt)) { - prop_warn(prop, "leading whitespace ignored"); - while (isspace(*prompt)) - prompt++; - } - if (current_entry->prompt && current_entry != &rootmenu) - prop_warn(prop, "prompt redefined"); + /* append property to the prop list of symbol */ + if (current_entry->sym) { + struct property **propp; - /* Apply all upper menus' visibilities to actual prompts. */ - if(type == P_PROMPT) { - struct menu *menu = current_entry; + for (propp = ¤t_entry->sym->prop; + *propp; + propp = &(*propp)->next) + ; + *propp = prop; + } - while ((menu = menu->parent) != NULL) { - struct expr *dup_expr; + return prop; +} - 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); +struct property *menu_add_prompt(enum prop_type type, char *prompt, + struct expr *dep) +{ + struct property *prop = menu_add_prop(type, NULL, dep); - prop->visible.expr - = expr_alloc_and(prop->visible.expr, - dup_expr); - } - } + if (isspace(*prompt)) { + prop_warn(prop, "leading whitespace ignored"); + while (isspace(*prompt)) + prompt++; + } + if (current_entry->prompt) + 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) { + struct expr *dup_expr; - current_entry->prompt = prop; + 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, + dup_expr); + } } + + current_entry->prompt = prop; prop->text = prompt; return prop; } -struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) -{ - return menu_add_prop(type, prompt, NULL, dep); -} - void menu_add_visibility(struct expr *expr) { current_entry->visibility = expr_alloc_and(current_entry->visibility, @@ -187,37 +203,34 @@ void menu_add_visibility(struct expr *expr) void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) { - menu_add_prop(type, NULL, expr, dep); + menu_add_prop(type, expr, dep); } void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) { - menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); + menu_add_prop(type, expr_alloc_symbol(sym), dep); } -void menu_add_option(int token, char *arg) +void menu_add_option_modules(void) { - switch (token) { - case T_OPT_MODULES: - 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) - sym_defconfig_list = current_entry->sym; - else if (sym_defconfig_list != current_entry->sym) - zconf_error("trying to redefine defconfig symbol"); - sym_defconfig_list->flags |= SYMBOL_AUTO; - break; - case T_OPT_ALLNOCONFIG_Y: - current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; - break; - } + 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; +} + +void menu_add_option_defconfig_list(void) +{ + if (!sym_defconfig_list) + sym_defconfig_list = current_entry->sym; + else if (sym_defconfig_list != current_entry->sym) + zconf_error("trying to redefine defconfig symbol"); + sym_defconfig_list->flags |= SYMBOL_NO_WRITE; +} + +void menu_add_option_allnoconfig_y(void) +{ + current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; } static int menu_validate_number(struct symbol *sym, struct symbol *sym2) @@ -329,12 +342,10 @@ void menu_finalize(struct menu *parent) * choice value symbols. */ parentdep = expr_alloc_symbol(sym); - } else if (parent->prompt) - /* Menu node for 'menu' */ - parentdep = parent->prompt->visible.expr; - else - /* Menu node for 'if' */ + } else { + /* Menu node for 'menu', 'if' */ parentdep = parent->dep; + } /* For each child menu node... */ for (menu = parent->list; menu; menu = menu->next) { @@ -701,6 +712,21 @@ const char *menu_get_help(struct menu *menu) return ""; } +static void get_def_str(struct gstr *r, struct menu *menu) +{ + str_printf(r, "Defined at %s:%d\n", + menu->file->name, menu->lineno); +} + +static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix) +{ + if (!expr_is_yes(expr)) { + str_append(r, prefix); + expr_gstr_print(expr, r); + str_append(r, "\n"); + } +} + static void get_prompt_str(struct gstr *r, struct property *prop, struct list_head *head) { @@ -708,7 +734,20 @@ static void get_prompt_str(struct gstr *r, struct property *prop, struct menu *submenu[8], *menu, *location = NULL; struct jump_key *jump = NULL; - str_printf(r, "Prompt: %s\n", prop->text); + str_printf(r, " Prompt: %s\n", prop->text); + + get_dep_str(r, prop->menu->dep, " Depends on: "); + /* + * Most prompts in Linux have visibility that exactly matches their + * dependencies. For these, we print only the dependencies to improve + * readability. However, prompts with inline "if" expressions and + * prompts with a parent that has a "visible if" expression have + * differing dependencies and visibility. In these rare cases, we + * print both. + */ + if (!expr_eq(prop->menu->dep, prop->visible.expr)) + get_dep_str(r, prop->visible.expr, " Visible if: "); + menu = prop->menu->parent; for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { bool accessible = menu_is_visible(menu); @@ -758,18 +797,6 @@ 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; -} - static void get_symbol_props_str(struct gstr *r, struct symbol *sym, enum prop_type tok, const char *prefix) { @@ -809,32 +836,34 @@ static 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"); + + /* Print the definitions with prompts before the ones without */ + for_all_properties(sym, prop, P_SYMBOL) { + if (prop->menu->prompt) { + get_def_str(r, prop->menu); + get_prompt_str(r, prop->menu->prompt, head); + } + } + + for_all_properties(sym, prop, P_SYMBOL) { + if (!prop->menu->prompt) { + get_def_str(r, prop->menu); + get_dep_str(r, prop->menu->dep, " Depends on: "); } } - get_symbol_props_str(r, sym, P_SELECT, " Selects: "); + get_symbol_props_str(r, sym, P_SELECT, "Selects: "); if (sym->rev_dep.expr) { - expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, " Selected by [y]:\n"); - expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, " Selected by [m]:\n"); - expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "Selected by [y]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "Selected by [m]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "Selected by [n]:\n"); } - get_symbol_props_str(r, sym, P_IMPLY, " Implies: "); + get_symbol_props_str(r, sym, P_IMPLY, "Implies: "); if (sym->implied.expr) { - expr_gstr_print_revdep(sym->implied.expr, r, yes, " Implied by [y]:\n"); - expr_gstr_print_revdep(sym->implied.expr, r, mod, " Implied by [m]:\n"); - expr_gstr_print_revdep(sym->implied.expr, r, no, " Implied by [n]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, yes, "Implied by [y]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, mod, "Implied by [m]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, no, "Implied by [n]:\n"); } str_append(r, "\n\n");