From d6ee35764f270c699e165b15dc59f4e55546bfda Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 7 Jan 2008 21:09:55 +0100 Subject: kconfig: rename E_OR & friends to avoid name clash We had macros named the same as a set of enumeration values. It is legal code but very confusing to read - so rename the macros from E_* to EXPR_* Signed-off-by: Sam Ravnborg Cc: Roman Zippel --- scripts/kconfig/expr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts/kconfig/expr.c') diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 6f98dbfe70c..c8793d1d908 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -955,14 +955,14 @@ tristate expr_calc_value(struct expr *e) case E_AND: val1 = expr_calc_value(e->left.expr); val2 = expr_calc_value(e->right.expr); - return E_AND(val1, val2); + return EXPR_AND(val1, val2); case E_OR: val1 = expr_calc_value(e->left.expr); val2 = expr_calc_value(e->right.expr); - return E_OR(val1, val2); + return EXPR_OR(val1, val2); case E_NOT: val1 = expr_calc_value(e->left.expr); - return E_NOT(val1); + return EXPR_NOT(val1); case E_EQUAL: sym_calc_value(e->left.sym); sym_calc_value(e->right.sym); -- cgit v1.2.3-70-g09d2 From 7a962923359768e04137125bd479fd0dfa6117d3 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Mon, 14 Jan 2008 04:50:23 +0100 Subject: kconfig: explicitly introduce expression list Rename E_CHOICE to E_LIST to explicitly add support for expression lists. Add a helper macro expr_list_for_each_sym to more easily iterate over the list. Signed-off-by: Roman Zippel Signed-off-by: Sam Ravnborg --- scripts/kconfig/confdata.c | 8 ++++---- scripts/kconfig/expr.c | 16 ++++++++-------- scripts/kconfig/expr.h | 5 ++++- scripts/kconfig/menu.c | 2 +- scripts/kconfig/symbol.c | 13 +++++++------ 5 files changed, 24 insertions(+), 20 deletions(-) (limited to 'scripts/kconfig/expr.c') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 497a19e85a0..ee5fe943d58 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -312,7 +312,7 @@ load: int conf_read(const char *name) { - struct symbol *sym; + struct symbol *sym, *choice_sym; struct property *prop; struct expr *e; int i, flags; @@ -353,9 +353,9 @@ int conf_read(const char *name) */ prop = sym_get_choice_prop(sym); flags = sym->flags; - for (e = prop->expr; e; e = e->left.expr) - if (e->right.sym->visible != no) - flags &= e->right.sym->flags; + expr_list_for_each_sym(prop->expr, e, choice_sym) + if (choice_sym->visible != no) + flags &= choice_sym->flags; sym->flags &= flags | ~SYMBOL_DEF_USER; } diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index c8793d1d908..13788ada522 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -87,7 +87,7 @@ struct expr *expr_copy(struct expr *org) break; case E_AND: case E_OR: - case E_CHOICE: + case E_LIST: e->left.expr = expr_copy(org->left.expr); e->right.expr = expr_copy(org->right.expr); break; @@ -217,7 +217,7 @@ int expr_eq(struct expr *e1, struct expr *e2) expr_free(e2); trans_count = old_count; return res; - case E_CHOICE: + case E_LIST: case E_RANGE: case E_NONE: /* panic */; @@ -648,7 +648,7 @@ struct expr *expr_transform(struct expr *e) case E_EQUAL: case E_UNEQUAL: case E_SYMBOL: - case E_CHOICE: + case E_LIST: break; default: e->left.expr = expr_transform(e->left.expr); @@ -932,7 +932,7 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb break; case E_SYMBOL: return expr_alloc_comp(type, e->left.sym, sym); - case E_CHOICE: + case E_LIST: case E_RANGE: case E_NONE: /* panic */; @@ -1000,9 +1000,9 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2) if (t2 == E_OR) return 1; case E_OR: - if (t2 == E_CHOICE) + if (t2 == E_LIST) return 1; - case E_CHOICE: + case E_LIST: if (t2 == 0) return 1; default: @@ -1053,11 +1053,11 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char * fn(data, NULL, " && "); expr_print(e->right.expr, fn, data, E_AND); break; - case E_CHOICE: + case E_LIST: fn(data, e->right.sym, e->right.sym->name); if (e->left.expr) { fn(data, NULL, " ^ "); - expr_print(e->left.expr, fn, data, E_CHOICE); + expr_print(e->left.expr, fn, data, E_LIST); } break; case E_RANGE: diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 1ee8b1642d3..b6f922c77e0 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -31,7 +31,7 @@ typedef enum tristate { } tristate; enum expr_type { - E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE + E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE }; union expr_data { @@ -48,6 +48,9 @@ struct expr { #define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) #define EXPR_NOT(dep) (2-(dep)) +#define expr_list_for_each_sym(l, e, s) \ + for (e = (l); e && (s = e->right.sym); e = e->left.expr) + struct expr_value { struct expr *expr; tristate tri; diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index e9deebe22ee..3637d1057e1 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -331,7 +331,7 @@ void menu_finalize(struct menu *parent) prop = sym_get_choice_prop(sym); for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr) ; - *ep = expr_alloc_one(E_CHOICE, NULL); + *ep = expr_alloc_one(E_LIST, NULL); (*ep)->right.sym = menu->sym; } if (menu->list && (!menu->prompt || !menu->prompt->text)) { diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index add068c8e51..a7dfc82fc85 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -247,8 +247,7 @@ static struct symbol *sym_calc_choice(struct symbol *sym) /* just get the first visible value */ prop = sym_get_choice_prop(sym); - for (e = prop->expr; e; e = e->left.expr) { - def_sym = e->right.sym; + expr_list_for_each_sym(prop->expr, e, def_sym) { sym_calc_visibility(def_sym); if (def_sym->visible != no) return def_sym; @@ -361,12 +360,14 @@ void sym_calc_value(struct symbol *sym) } if (sym_is_choice(sym)) { + struct symbol *choice_sym; int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); + prop = sym_get_choice_prop(sym); - for (e = prop->expr; e; e = e->left.expr) { - e->right.sym->flags |= flags; + expr_list_for_each_sym(prop->expr, e, choice_sym) { + choice_sym->flags |= flags; if (flags & SYMBOL_CHANGED) - sym_set_changed(e->right.sym); + sym_set_changed(choice_sym); } } } @@ -849,7 +850,7 @@ struct property *prop_alloc(enum prop_type type, struct symbol *sym) struct symbol *prop_get_symbol(struct property *prop) { if (prop->expr && (prop->expr->type == E_SYMBOL || - prop->expr->type == E_CHOICE)) + prop->expr->type == E_LIST)) return prop->expr->left.sym; return NULL; } -- cgit v1.2.3-70-g09d2 From f5eaa323eb6819d2f737ead42464efccaf2b98b9 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 24 Jan 2008 11:54:23 +0000 Subject: kconfig: tristate choices with mixed tristate and boolean values Change kconfig behavior so that mixing bool and tristate config settings in a choice is possible and has the desired effect of offering just the tristate options individually if the choice gets set to M, and a normal boolean selection if the choice gets set to Y. Also fix scripts/kconfig/conf's handling of children of choice values - there may be more than one immediate child, and all of them need to be processed. Signed-off-by: Jan Beulich Cc: "Roman Zippel" Signed-off-by: Sam Ravnborg --- scripts/kconfig/conf.c | 4 ++-- scripts/kconfig/expr.c | 10 ++++++++-- scripts/kconfig/menu.c | 38 +++++++++++++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 7 deletions(-) (limited to 'scripts/kconfig/expr.c') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index d1a0368bd43..fda63136ae6 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -400,9 +400,9 @@ static int conf_choice(struct menu *menu) continue; } sym_set_choice_value(sym, child->sym); - if (child->list) { + for (child = child->list; child; child = child->next) { indent += 2; - conf(child->list); + conf(child); indent -= 2; } return 1; diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 13788ada522..579ece4fa58 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -1034,12 +1034,18 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char * expr_print(e->left.expr, fn, data, E_NOT); break; case E_EQUAL: - fn(data, e->left.sym, e->left.sym->name); + if (e->left.sym->name) + fn(data, e->left.sym, e->left.sym->name); + else + fn(data, NULL, ""); fn(data, NULL, "="); fn(data, e->right.sym, e->right.sym->name); break; case E_UNEQUAL: - fn(data, e->left.sym, e->left.sym->name); + if (e->left.sym->name) + fn(data, e->left.sym, e->left.sym->name); + else + fn(data, NULL, ""); fn(data, NULL, "!="); fn(data, e->right.sym, e->right.sym->name); break; diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index e6ef171e5b1..fdad17367f6 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -242,9 +242,11 @@ void menu_finalize(struct menu *parent) for (menu = parent->list; menu; menu = menu->next) { if (menu->sym) { current_entry = parent; - menu_set_type(menu->sym->type); + if (sym->type == S_UNKNOWN) + menu_set_type(menu->sym->type); current_entry = menu; - menu_set_type(sym->type); + if (menu->sym->type == S_UNKNOWN) + menu_set_type(sym->type); break; } } @@ -329,7 +331,37 @@ void menu_finalize(struct menu *parent) "values not supported"); } current_entry = menu; - menu_set_type(sym->type); + if (menu->sym->type == S_UNKNOWN) + menu_set_type(sym->type); + /* Non-tristate choice values of tristate choices must + * depend on the choice being set to Y. The choice + * values' dependencies were propagated to their + * properties above, so the change here must be re- + * propagated. */ + if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) { + basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes); + basedep = expr_alloc_and(basedep, menu->dep); + basedep = expr_eliminate_dups(basedep); + menu->dep = basedep; + for (prop = menu->sym->prop; prop; prop = prop->next) { + if (prop->menu != menu) + continue; + dep = expr_alloc_and(expr_copy(basedep), + prop->visible.expr); + dep = expr_eliminate_dups(dep); + dep = expr_trans_bool(dep); + prop->visible.expr = dep; + if (prop->type == P_SELECT) { + struct symbol *es = prop_get_symbol(prop); + dep2 = expr_alloc_symbol(menu->sym); + dep = expr_alloc_and(dep2, + expr_copy(dep)); + dep = expr_alloc_or(es->rev_dep.expr, dep); + dep = expr_eliminate_dups(dep); + es->rev_dep.expr = dep; + } + } + } menu_add_symbol(P_CHOICE, sym, NULL); prop = sym_get_choice_prop(sym); for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr) -- cgit v1.2.3-70-g09d2