X-Git-Url: https://jxself.org/git/?p=carl9170fw.git;a=blobdiff_plain;f=config%2Fmenu.c;h=47bec3434fef16f1b0c46e0f8d908ee704aa57ca;hp=c8cec26c25354658c0879abe56df322e5087b626;hb=2f1132cbcec40e431991cda7ff3744455b46c3df;hpb=4d11907abfeb7a1de0080a8c7a7e67ce4fa231db diff --git a/config/menu.c b/config/menu.c index c8cec26..47bec34 100644 --- a/config/menu.c +++ b/config/menu.c @@ -62,13 +62,8 @@ void menu_add_entry(struct symbol *sym) menu_add_symbol(P_SYMBOL, sym, NULL); } -void menu_end_entry(void) -{ -} - struct menu *menu_add_menu(void) { - menu_end_entry(); last_entry_ptr = ¤t_entry->list; return current_menu = current_entry; } @@ -110,7 +105,7 @@ static struct expr *rewrite_m(struct expr *e) void menu_add_dep(struct expr *dep) { - current_entry->dep = expr_alloc_and(current_entry->dep, rewrite_m(dep)); + current_entry->dep = expr_alloc_and(current_entry->dep, dep); } void menu_set_type(int type) @@ -135,7 +130,7 @@ static struct property *menu_add_prop(enum prop_type type, char *prompt, struct prop->menu = current_entry; prop->expr = expr; - prop->visible.expr = rewrite_m(dep); + prop->visible.expr = dep; if (prompt) { if (isspace(*prompt)) { @@ -274,13 +269,13 @@ static void sym_check_prop(struct symbol *sym) if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) prop_warn(prop, "config symbol '%s' uses %s, but is " - "not boolean or tristate", sym->name, use); + "not bool or tristate", sym->name, use); else if (sym2->type != S_UNKNOWN && sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE) prop_warn(prop, "'%s' has wrong type. '%s' only " - "accept arguments of boolean and " + "accept arguments of bool and " "tristate type", sym2->name, use); break; case P_RANGE: @@ -340,7 +335,8 @@ void menu_finalize(struct menu *parent) * Propagate parent dependencies to the child menu * node, also rewriting and simplifying expressions */ - basedep = expr_transform(menu->dep); + basedep = rewrite_m(menu->dep); + basedep = expr_transform(basedep); basedep = expr_alloc_and(expr_copy(parentdep), basedep); basedep = expr_eliminate_dups(basedep); menu->dep = basedep; @@ -383,7 +379,8 @@ void menu_finalize(struct menu *parent) * property's condition, rewriting and * simplifying expressions at the same time */ - dep = expr_transform(prop->visible.expr); + dep = rewrite_m(prop->visible.expr); + dep = expr_transform(dep); dep = expr_alloc_and(expr_copy(basedep), dep); dep = expr_eliminate_dups(dep); if (menu->sym && menu->sym->type != S_TRISTATE) @@ -406,6 +403,9 @@ void menu_finalize(struct menu *parent) } } + if (sym && sym_is_choice(sym)) + expr_free(parentdep); + /* * Recursively process children in the same fashion before * moving on @@ -413,31 +413,70 @@ void menu_finalize(struct menu *parent) for (menu = parent->list; menu; menu = menu->next) menu_finalize(menu); } else if (sym) { + /* + * Automatic submenu creation. If sym is a symbol and A, B, C, + * ... are consecutive items (symbols, menus, ifs, etc.) that + * all depend on sym, then the following menu structure is + * created: + * + * sym + * +-A + * +-B + * +-C + * ... + * + * This also works recursively, giving the following structure + * if A is a symbol and B depends on A: + * + * sym + * +-A + * | +-B + * +-C + * ... + */ + basedep = parent->prompt ? parent->prompt->visible.expr : NULL; basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); basedep = expr_eliminate_dups(expr_transform(basedep)); + + /* Examine consecutive elements after sym */ last_menu = NULL; for (menu = parent->next; menu; menu = menu->next) { dep = menu->prompt ? menu->prompt->visible.expr : menu->dep; if (!expr_contains_symbol(dep, sym)) + /* No dependency, quit */ break; if (expr_depends_symbol(dep, sym)) + /* Absolute dependency, put in submenu */ goto next; + + /* + * Also consider it a dependency on sym if our + * dependencies contain sym and are a "superset" of + * sym's dependencies, e.g. '(sym || Q) && R' when sym + * depends on R. + * + * Note that 'R' might be from an enclosing menu or if, + * making this a more common case than it might seem. + */ dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no); dep = expr_eliminate_dups(expr_transform(dep)); dep2 = expr_copy(basedep); expr_eliminate_eq(&dep, &dep2); expr_free(dep); if (!expr_is_yes(dep2)) { + /* Not superset, quit */ expr_free(dep2); break; } + /* Superset, put in submenu */ expr_free(dep2); next: menu_finalize(menu); menu->parent = parent; last_menu = menu; } + expr_free(basedep); if (last_menu) { parent->list = parent->next; parent->next = last_menu->next;