This is a fairly brute force approach to allowing a Kconfig "select" to specify an excplicit value for the selected config sybmol. The syntax of select is changed to: "select" <symbol> [<expr>] ["if" expr] The approach taken is to add a list of <value, dependency expression> pairs to the symbol and check them whenever the reverse depends (from a current-style select) are checked. Signed-off-by: Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx> --- Documentation/kbuild/kconfig-language.txt | 7 +- scripts/kconfig/expr.h | 9 + scripts/kconfig/lkc.h | 1 + scripts/kconfig/menu.c | 70 +++++- scripts/kconfig/symbol.c | 88 +++++++- scripts/kconfig/zconf.tab.c_shipped | 352 +++++++++++++++-------------- scripts/kconfig/zconf.y | 17 ++- 7 files changed, 356 insertions(+), 188 deletions(-) This is a work in progress, though it is possible to set values. I have not done a great deal of testing. I would like comments on the approach (and the actual code as the kconfig code is pretty dense :-)). This is built on top of the kbuild tree that is in linux-next (git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6.git#for-next) merged with Linus' tree of a few days ago (commit 2f7989efd4398d92b8adffce2e07dd043a0895fe "Merge master.kernel.org:/home/rmk/linux-2.6-arm"). diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt index b472e4e..b1fb180 100644 --- a/Documentation/kbuild/kconfig-language.txt +++ b/Documentation/kbuild/kconfig-language.txt @@ -95,14 +95,15 @@ applicable everywhere (see syntax). bool "foo" default y -- reverse dependencies: "select" <symbol> ["if" <expr>] +- reverse dependencies: "select" <symbol> [<expr>] ["if" <expr>] While normal dependencies reduce the upper limit of a symbol (see below), reverse dependencies can be used to force a lower limit of another symbol. The value of the current menu symbol is used as the minimal value <symbol> can be set to. If <symbol> is selected multiple times, the limit is set to the largest selection. - Reverse dependencies can only be used with boolean or tristate - symbols. + Reverse dependencies without the optional <expr> can only be used with + boolean or tristate symbols. If the optional <expr> is supplied, + the <symbol> will be set to that value if possible. Note: select should be used with care. select will force a symbol to a value without visiting the dependencies. diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 75a31e4..7217c6d 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -56,6 +56,13 @@ struct expr_value { tristate tri; }; +struct expr_select_value { + struct expr *expr; + tristate tri; + struct expr *value; + struct expr_select_value *next; +}; + struct symbol_value { void *val; tristate tri; @@ -85,6 +92,7 @@ struct symbol { struct property *prop; struct expr_value dir_dep; struct expr_value rev_dep; + struct expr_select_value *val_dep; }; #define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) @@ -146,6 +154,7 @@ struct property { * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ struct file *file; /* what file was this property defined */ int lineno; /* what lineno was this property defined */ + struct expr *value; /* the optional P_SELECT value */ }; #define for_all_properties(sym, st, tok) \ diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index ce6549c..5176657 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -95,6 +95,7 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); +void menu_add_select(struct symbol *sym, struct expr *value, struct expr *dep); void menu_add_option(int token, char *arg); void menu_finalize(struct menu *parent); void menu_set_type(int type); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 1179989..f1211f3 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -161,6 +161,14 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); } +void menu_add_select(struct symbol *sym, struct expr *value, struct expr *dep) +{ + struct property *p; + + p = menu_add_prop(P_SELECT, NULL, expr_alloc_symbol(sym), dep); + p->value = value; +} + void menu_add_option(int token, char *arg) { struct property *prop; @@ -207,13 +215,22 @@ static void sym_check_prop(struct symbol *sym) prop_warn(prop, "config symbol '%s' uses select, but is " "not boolean or tristate", sym->name); - else if (sym2->type != S_UNKNOWN && + else if (prop->value == NULL && + sym2->type != S_UNKNOWN && sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE) prop_warn(prop, - "'%s' has wrong type. 'select' only " - "accept arguments of boolean and " - "tristate type", sym2->name); + "'%s' has wrong type. 'select' without a " + "value only accepts arguments of boolean " + "and tristate type", sym2->name); + else if (prop->value != NULL && + (sym2->type == S_INT || + sym2->type == S_HEX || + sym2->type == S_STRING) && + prop->value->type != E_SYMBOL) + prop_warn(prop, + "select value for config symbol '%s'" + " must be a single symbol", sym2->name); break; case P_RANGE: if (sym->type != S_INT && sym->type != S_HEX) @@ -229,6 +246,25 @@ static void sym_check_prop(struct symbol *sym) } } +static void finalize_select(struct symbol *sym, struct property *prop, + struct expr *dep) +{ + struct symbol *es = prop_get_symbol(prop); + struct expr_select_value *esv; + + if (prop->value) { + esv = malloc(sizeof *esv); + esv->expr = expr_alloc_and(expr_alloc_symbol(sym), + expr_copy(dep)); + esv->value = prop->value; + esv->next = es->val_dep; + es->val_dep = esv; + } else { + es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, + expr_alloc_and(expr_alloc_symbol(sym), expr_copy(dep))); + } +} + void menu_finalize(struct menu *parent) { struct menu *menu, *last_menu; @@ -279,11 +315,8 @@ void menu_finalize(struct menu *parent) if (menu->sym && menu->sym->type != S_TRISTATE) dep = expr_trans_bool(dep); prop->visible.expr = dep; - if (prop->type == P_SELECT) { - struct symbol *es = prop_get_symbol(prop); - es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, - expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); - } + if (prop->type == P_SELECT) + finalize_select(menu->sym, prop, dep); } } for (menu = parent->list; menu; menu = menu->next) @@ -389,9 +422,15 @@ void menu_finalize(struct menu *parent) } if (sym && !sym_is_optional(sym) && parent->prompt) { + struct expr_select_value *esv; + sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, expr_alloc_and(parent->prompt->visible.expr, expr_alloc_symbol(&symbol_mod))); + for (esv = sym->val_dep; esv; esv = esv->next) + esv->expr = expr_alloc_or(esv->expr, + expr_alloc_and(parent->prompt->visible.expr, + expr_alloc_symbol(&symbol_mod))); } } @@ -509,6 +548,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) { bool hit; struct property *prop; + struct expr_select_value *esv; if (sym && sym->name) { str_printf(r, "Symbol: %s [=%s]\n", sym->name, @@ -533,6 +573,11 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) } else str_printf(r, " && "); expr_gstr_print(prop->expr, r); + if (prop->value) { + str_printf(r, " (value="); + expr_gstr_print(prop->value, r); + str_printf(r, ")"); + } } if (hit) str_append(r, "\n"); @@ -541,6 +586,13 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) expr_gstr_print(sym->rev_dep.expr, r); str_append(r, "\n"); } + for (esv = sym->val_dep; esv; esv = esv->next) { + str_append(r, " Selected by: "); + expr_gstr_print(esv->expr, r); + str_append(r, " with value: "); + expr_gstr_print(esv->value, r); + str_append(r, "\n"); + } str_append(r, "\n\n"); } diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index c127fa3..8fbfc15 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -190,6 +190,7 @@ static void sym_calc_visibility(struct symbol *sym) { struct property *prop; tristate tri; + struct expr_select_value *esv; /* any prompt visible? */ tri = no; @@ -224,6 +225,15 @@ static void sym_calc_visibility(struct symbol *sym) sym->rev_dep.tri = tri; sym_set_changed(sym); } + for (esv = sym->val_dep; esv; esv = esv->next) { + tri = expr_calc_value(esv->expr); + if (tri == mod && sym_get_type(sym) == S_BOOLEAN) + tri = yes; + if (esv->tri != tri) { + esv->tri = tri; + sym_set_changed(sym); + } + } } static struct symbol *sym_calc_choice(struct symbol *sym) @@ -268,6 +278,8 @@ void sym_calc_value(struct symbol *sym) struct symbol_value newval, oldval; struct property *prop; struct expr *e; + struct expr_select_value *esv; + int got_sel_val; if (!sym) return; @@ -321,6 +333,9 @@ void sym_calc_value(struct symbol *sym) } if (sym->rev_dep.tri != no) sym->flags |= SYMBOL_WRITE; + for (esv = sym->val_dep; esv; esv = esv->next) + if (esv->tri != no) + sym->flags |= SYMBOL_WRITE; if (!sym_is_choice(sym)) { prop = sym_get_default_prop(sym); if (prop) { @@ -330,15 +345,34 @@ void sym_calc_value(struct symbol *sym) } } calc_newval: - if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { - fprintf(stderr, "warning: ("); - expr_fprint(sym->rev_dep.expr, stderr); - fprintf(stderr, ") selects %s which has unmet direct dependencies (", - sym->name); - expr_fprint(sym->dir_dep.expr, stderr); - fprintf(stderr, ")\n"); + if (sym->dir_dep.tri == no) { + if (sym->rev_dep.tri != no) { + fprintf(stderr, "warning: ("); + expr_fprint(sym->rev_dep.expr, stderr); + fprintf(stderr, ") selects %s which has unmet direct dependencies (", + sym->name); + expr_fprint(sym->dir_dep.expr, stderr); + fprintf(stderr, ")\n"); + } + for (esv = sym->val_dep; esv; esv = esv->next) { + if ((esv->tri != no) && + (expr_calc_value(esv->value) != no)) { + fprintf(stderr, "warning: ("); + expr_fprint(esv->expr, stderr); + fprintf(stderr, ") selects %s (with value ", + sym->name); + expr_fprint(esv->value, stderr); + fprintf(stderr, ") which has unmet direct dependencies ("); + expr_fprint(sym->dir_dep.expr, stderr); + fprintf(stderr, ")\n"); + } + } } newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); + for (esv = sym->val_dep; esv; esv = esv->next) + if (esv->tri != no) + newval.tri = EXPR_OR(newval.tri, + expr_calc_value(esv->value)); } if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) newval.tri = yes; @@ -353,6 +387,23 @@ void sym_calc_value(struct symbol *sym) break; } } + got_sel_val = 0; + for (esv = sym->val_dep; esv; esv = esv->next) { + if (esv->tri != no) { + struct symbol *ss = esv->value->left.sym; + + if (got_sel_val) { + /* warn of more than one value selected */ + } else { + sym->flags |= SYMBOL_WRITE; + sym_calc_value(ss); + newval.val = ss->curr.val; + got_sel_val = 1; + } + } + } + if (got_sel_val) + break; prop = sym_get_default_prop(sym); if (prop) { struct symbol *ds = prop_get_symbol(prop); @@ -432,6 +483,8 @@ void sym_set_all_changed(void) bool sym_tristate_within_range(struct symbol *sym, tristate val) { int type = sym_get_type(sym); + struct expr_select_value *esv; + tristate tri; if (sym->visible == no) return false; @@ -441,11 +494,14 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) if (type == S_BOOLEAN && val == mod) return false; - if (sym->visible <= sym->rev_dep.tri) + tri = sym->rev_dep.tri; + for (esv = sym->val_dep; esv; esv = esv->next) + tri = EXPR_OR(tri, esv->tri); + if (sym->visible <= tri) return false; if (sym_is_choice_value(sym) && sym->visible == yes) return val == yes; - return val >= sym->rev_dep.tri && val <= sym->visible; + return val >= tri && val <= sym->visible; } bool sym_set_tristate_value(struct symbol *sym, tristate val) @@ -666,7 +722,13 @@ const char *sym_get_string_value(struct symbol *sym) bool sym_is_changable(struct symbol *sym) { - return sym->visible > sym->rev_dep.tri; + tristate tri = sym->rev_dep.tri; + struct expr_select_value *esv; + + for (esv = sym->val_dep; esv; esv = esv->next) + tri = EXPR_OR(tri, esv->tri); + + return sym->visible > tri; } static unsigned strhash(const char *s) @@ -819,10 +881,16 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) { struct symbol *sym2; struct property *prop; + struct expr_select_value *esv; sym2 = sym_check_expr_deps(sym->rev_dep.expr); if (sym2) return sym2; + for (esv = sym->val_dep; esv; esv = esv->next) { + sym2 = sym_check_expr_deps(esv->expr); + if (sym2) + return sym2; + } for (prop = sym->prop; prop; prop = prop->next) { if (prop->type == P_CHOICE || prop->type == P_SELECT) diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped index 32a9eef..307bf23 100644 --- a/scripts/kconfig/zconf.tab.c_shipped +++ b/scripts/kconfig/zconf.tab.c_shipped @@ -419,16 +419,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 259 +#define YYLAST 268 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 35 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 46 /* YYNRULES -- Number of rules. */ -#define YYNRULES 110 +#define YYNRULES 111 /* YYNRULES -- Number of states. */ -#define YYNSTATES 180 +#define YYNSTATES 183 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 @@ -480,14 +480,14 @@ static const yytype_uint16 yyprhs[] = 28, 33, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 67, 70, 74, 77, 81, 84, 85, 88, 91, 94, 97, 100, 103, 107, - 112, 117, 122, 128, 132, 133, 137, 138, 141, 145, - 148, 150, 154, 155, 158, 161, 164, 167, 170, 175, - 179, 182, 187, 188, 191, 195, 197, 201, 202, 205, - 208, 211, 215, 218, 220, 224, 225, 228, 231, 234, - 238, 242, 245, 248, 251, 252, 255, 258, 261, 266, - 267, 270, 272, 274, 277, 280, 283, 285, 288, 289, - 292, 294, 298, 302, 306, 309, 313, 317, 319, 321, - 322 + 112, 117, 122, 128, 134, 138, 139, 143, 144, 147, + 151, 154, 156, 160, 161, 164, 167, 170, 173, 176, + 181, 185, 188, 193, 194, 197, 201, 203, 207, 208, + 211, 214, 217, 221, 224, 226, 230, 231, 234, 237, + 240, 244, 248, 251, 254, 257, 258, 261, 264, 267, + 272, 273, 276, 278, 280, 283, 286, 289, 291, 294, + 295, 298, 300, 304, 308, 312, 315, 319, 323, 325, + 327, 328 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ @@ -505,27 +505,27 @@ static const yytype_int8 yyrhs[] = -1, 45, 72, -1, 45, 70, -1, 45, 40, -1, 45, 30, -1, 19, 73, 30, -1, 18, 74, 77, 30, -1, 20, 78, 77, 30, -1, 21, 25, 77, - 30, -1, 22, 79, 79, 77, 30, -1, 23, 48, - 30, -1, -1, 48, 25, 49, -1, -1, 33, 74, - -1, 7, 80, 30, -1, 50, 54, -1, 75, -1, - 51, 56, 52, -1, -1, 54, 55, -1, 54, 72, - -1, 54, 70, -1, 54, 30, -1, 54, 40, -1, - 18, 74, 77, 30, -1, 19, 73, 30, -1, 17, - 30, -1, 20, 25, 77, 30, -1, -1, 56, 39, - -1, 14, 78, 76, -1, 75, -1, 57, 60, 58, - -1, -1, 60, 39, -1, 60, 64, -1, 60, 53, - -1, 4, 74, 30, -1, 61, 71, -1, 75, -1, - 62, 65, 63, -1, -1, 65, 39, -1, 65, 64, - -1, 65, 53, -1, 6, 74, 30, -1, 9, 74, - 30, -1, 67, 71, -1, 12, 30, -1, 69, 13, - -1, -1, 71, 72, -1, 71, 30, -1, 71, 40, - -1, 16, 24, 78, 30, -1, -1, 74, 77, -1, - 25, -1, 26, -1, 5, 30, -1, 8, 30, -1, - 15, 30, -1, 30, -1, 76, 30, -1, -1, 14, - 78, -1, 79, -1, 79, 33, 79, -1, 79, 27, - 79, -1, 29, 78, 28, -1, 34, 78, -1, 78, - 31, 78, -1, 78, 32, 78, -1, 25, -1, 26, - -1, -1, 25, -1 + 30, -1, 21, 25, 78, 77, 30, -1, 22, 79, + 79, 77, 30, -1, 23, 48, 30, -1, -1, 48, + 25, 49, -1, -1, 33, 74, -1, 7, 80, 30, + -1, 50, 54, -1, 75, -1, 51, 56, 52, -1, + -1, 54, 55, -1, 54, 72, -1, 54, 70, -1, + 54, 30, -1, 54, 40, -1, 18, 74, 77, 30, + -1, 19, 73, 30, -1, 17, 30, -1, 20, 25, + 77, 30, -1, -1, 56, 39, -1, 14, 78, 76, + -1, 75, -1, 57, 60, 58, -1, -1, 60, 39, + -1, 60, 64, -1, 60, 53, -1, 4, 74, 30, + -1, 61, 71, -1, 75, -1, 62, 65, 63, -1, + -1, 65, 39, -1, 65, 64, -1, 65, 53, -1, + 6, 74, 30, -1, 9, 74, 30, -1, 67, 71, + -1, 12, 30, -1, 69, 13, -1, -1, 71, 72, + -1, 71, 30, -1, 71, 40, -1, 16, 24, 78, + 30, -1, -1, 74, 77, -1, 25, -1, 26, -1, + 5, 30, -1, 8, 30, -1, 15, 30, -1, 30, + -1, 76, 30, -1, -1, 14, 78, -1, 79, -1, + 79, 33, 79, -1, 79, 27, 79, -1, 29, 78, + 28, -1, 34, 78, -1, 78, 31, 78, -1, 78, + 32, 78, -1, 25, -1, 26, -1, -1, 25, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ @@ -535,14 +535,14 @@ static const yytype_uint16 yyrline[] = 117, 121, 125, 125, 125, 125, 125, 125, 125, 129, 130, 131, 132, 133, 134, 138, 139, 145, 153, 159, 167, 177, 179, 180, 181, 182, 183, 184, 187, 195, - 201, 211, 217, 223, 226, 228, 239, 240, 245, 254, - 259, 267, 270, 272, 273, 274, 275, 276, 279, 285, - 296, 302, 312, 314, 319, 327, 335, 338, 340, 341, - 342, 347, 354, 359, 367, 370, 372, 373, 374, 377, - 385, 392, 399, 405, 412, 414, 415, 416, 419, 427, - 429, 434, 435, 438, 439, 440, 444, 445, 448, 449, - 452, 453, 454, 455, 456, 457, 458, 461, 462, 465, - 466 + 201, 211, 217, 223, 229, 232, 234, 245, 246, 251, + 260, 265, 273, 276, 278, 279, 280, 281, 282, 285, + 291, 302, 308, 318, 320, 325, 333, 341, 344, 346, + 347, 348, 353, 360, 365, 373, 376, 378, 379, 380, + 383, 391, 398, 405, 411, 418, 420, 421, 422, 425, + 433, 435, 440, 441, 444, 445, 446, 450, 451, 454, + 455, 458, 459, 460, 461, 462, 463, 464, 467, 468, + 471, 472 }; #endif @@ -590,14 +590,14 @@ static const yytype_uint8 yyr1[] = 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40, 40, 41, 42, 43, 44, 45, 45, 45, 45, 45, 45, 45, 46, 46, - 46, 46, 46, 47, 48, 48, 49, 49, 50, 51, - 52, 53, 54, 54, 54, 54, 54, 54, 55, 55, - 55, 55, 56, 56, 57, 58, 59, 60, 60, 60, - 60, 61, 62, 63, 64, 65, 65, 65, 65, 66, - 67, 68, 69, 70, 71, 71, 71, 71, 72, 73, - 73, 74, 74, 75, 75, 75, 76, 76, 77, 77, - 78, 78, 78, 78, 78, 78, 78, 79, 79, 80, - 80 + 46, 46, 46, 46, 47, 48, 48, 49, 49, 50, + 51, 52, 53, 54, 54, 54, 54, 54, 54, 55, + 55, 55, 55, 56, 56, 57, 58, 59, 60, 60, + 60, 60, 61, 62, 63, 64, 65, 65, 65, 65, + 66, 67, 68, 69, 70, 71, 71, 71, 71, 72, + 73, 73, 74, 74, 75, 75, 75, 76, 76, 77, + 77, 78, 78, 78, 78, 78, 78, 78, 79, 79, + 80, 80 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -607,14 +607,14 @@ static const yytype_uint8 yyr2[] = 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 3, 2, 3, 2, 0, 2, 2, 2, 2, 2, 2, 3, 4, - 4, 4, 5, 3, 0, 3, 0, 2, 3, 2, - 1, 3, 0, 2, 2, 2, 2, 2, 4, 3, - 2, 4, 0, 2, 3, 1, 3, 0, 2, 2, - 2, 3, 2, 1, 3, 0, 2, 2, 2, 3, - 3, 2, 2, 2, 0, 2, 2, 2, 4, 0, - 2, 1, 1, 2, 2, 2, 1, 2, 0, 2, - 1, 3, 3, 3, 2, 3, 3, 1, 1, 0, - 1 + 4, 4, 5, 5, 3, 0, 3, 0, 2, 3, + 2, 1, 3, 0, 2, 2, 2, 2, 2, 4, + 3, 2, 4, 0, 2, 3, 1, 3, 0, 2, + 2, 2, 3, 2, 1, 3, 0, 2, 2, 2, + 3, 3, 2, 2, 2, 0, 2, 2, 2, 4, + 0, 2, 1, 1, 2, 2, 2, 1, 2, 0, + 2, 1, 3, 3, 3, 2, 3, 3, 1, 1, + 0, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -622,31 +622,32 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 3, 0, 0, 1, 0, 0, 0, 0, 0, 109, + 3, 0, 0, 1, 0, 0, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 12, 16, 13, 14, 18, 15, 17, 0, 19, 0, 4, 31, 22, 31, - 23, 52, 62, 5, 67, 20, 84, 75, 6, 24, - 84, 21, 8, 11, 91, 92, 0, 0, 93, 0, - 110, 0, 94, 0, 0, 0, 107, 108, 0, 0, - 0, 100, 95, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 96, 7, 71, 79, 48, 80, 27, - 29, 0, 104, 0, 0, 64, 0, 0, 9, 10, - 0, 0, 0, 0, 89, 0, 0, 0, 44, 0, - 37, 36, 32, 33, 0, 35, 34, 0, 0, 89, - 0, 56, 57, 53, 55, 54, 63, 51, 50, 68, - 70, 66, 69, 65, 86, 87, 85, 76, 78, 74, - 77, 73, 97, 103, 105, 106, 102, 101, 26, 82, - 0, 98, 0, 98, 98, 98, 0, 0, 0, 83, - 60, 98, 0, 98, 0, 0, 0, 38, 90, 0, - 0, 98, 46, 43, 25, 0, 59, 0, 88, 99, - 39, 40, 41, 0, 0, 45, 58, 61, 42, 47 + 23, 53, 63, 5, 68, 20, 85, 76, 6, 24, + 85, 21, 8, 11, 92, 93, 0, 0, 94, 0, + 111, 0, 95, 0, 0, 0, 108, 109, 0, 0, + 0, 101, 96, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 97, 7, 72, 80, 49, 81, 27, + 29, 0, 105, 0, 0, 65, 0, 0, 9, 10, + 0, 0, 0, 0, 90, 0, 0, 0, 45, 0, + 37, 36, 32, 33, 0, 35, 34, 0, 0, 90, + 0, 57, 58, 54, 56, 55, 64, 52, 51, 69, + 71, 67, 70, 66, 87, 88, 86, 77, 79, 75, + 78, 74, 98, 104, 106, 107, 103, 102, 26, 83, + 0, 99, 0, 99, 99, 99, 0, 0, 0, 84, + 61, 99, 0, 99, 0, 0, 0, 38, 91, 0, + 0, 99, 99, 47, 44, 25, 0, 60, 0, 89, + 100, 39, 40, 41, 0, 0, 0, 46, 59, 62, + 42, 43, 48 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 2, 25, 26, 101, 27, 28, 29, 30, - 65, 102, 103, 147, 175, 31, 32, 117, 33, 67, + 65, 102, 103, 147, 177, 31, 32, 117, 33, 67, 113, 68, 34, 121, 35, 69, 36, 37, 129, 38, 71, 39, 40, 41, 104, 105, 70, 106, 142, 143, 42, 74, 156, 60, 61, 51 @@ -661,65 +662,67 @@ static const yytype_int16 yypact[] = 33, -1, 27, 40, -3, 38, -80, -80, -80, -80, -80, -80, -80, 71, -80, 77, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, 57, 61, -80, 63, - -80, 76, -80, 87, 101, 133, -80, -80, -3, -3, - 195, -6, -80, 136, 149, 39, 104, 65, 150, 5, - 194, 5, 167, -80, 176, -80, -80, -80, -80, -80, - -80, 68, -80, -3, -3, 176, 72, 72, -80, -80, - 177, 187, 78, -1, -1, -3, 196, 72, -80, 222, - -80, -80, -80, -80, 221, -80, -80, 205, -1, -1, - 211, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, 57, 63, -80, 76, + -80, 87, -80, 101, 115, 128, -80, -80, -3, -3, + 209, -6, -80, 137, 162, 39, 104, 65, 208, 5, + 196, 5, 169, -80, 166, -80, -80, -80, -80, -80, + -80, 68, -80, -3, -3, 166, 72, 72, -80, -80, + 168, 178, 78, -1, -1, -3, 184, 72, -80, 219, + -80, -80, -80, -80, 211, -80, -80, 195, -1, -1, + 205, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, 206, -80, -80, -80, -80, -80, - -3, 223, 209, 223, 197, 223, 72, 7, 210, -80, - -80, 223, 212, 223, 201, -3, 213, -80, -80, 214, - 215, 223, 208, -80, -80, 216, -80, 217, -80, 113, - -80, -80, -80, 218, -1, -80, -80, -80, -80, -80 + -80, -80, -80, -80, 199, -80, -80, -80, -80, -80, + -3, 220, 206, 220, 201, 130, 72, 7, 217, -80, + -80, 220, 218, 220, 212, -3, 221, -80, -80, 222, + 223, 201, 220, 216, -80, -80, 224, -80, 225, -80, + 150, -80, -80, -80, 226, 227, -1, -80, -80, -80, + -80, -80, -80 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -80, -80, -80, -80, 122, -34, -80, -80, -80, -80, - 220, -80, -80, -80, -80, -80, -80, -80, 59, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, 125, - -80, -80, -80, -80, -80, 183, 219, 22, 142, -5, - 147, 192, 69, -54, -79, -80 + -80, -80, -80, -80, 92, -34, -80, -80, -80, -80, + 229, -80, -80, -80, -80, -80, -80, -80, 59, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, 124, + -80, -80, -80, -80, -80, 183, 228, 22, 151, -5, + 97, 202, 84, -54, -79, -80 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -82 +#define YYTABLE_NINF -83 static const yytype_int16 yytable[] = { 46, 47, 3, 49, 81, 82, 53, 136, 137, 6, 7, 8, 9, 10, 11, 12, 13, 43, 146, 14, 15, 86, 56, 57, 44, 45, 58, 87, 48, 134, - 135, 59, 162, 112, 50, 24, 125, 163, 125, -28, + 135, 59, 163, 112, 50, 24, 125, 164, 125, -28, 90, 144, -28, -28, -28, -28, -28, -28, -28, -28, -28, 91, 54, -28, -28, 92, -28, 93, 94, 95, - 96, 97, 98, 52, 99, 55, 90, 161, 62, 100, - -49, -49, 63, -49, -49, -49, -49, 91, 64, -49, - -49, 92, 107, 108, 109, 110, 154, 73, 141, 115, - 99, 75, 126, 76, 126, 111, 133, 56, 57, 83, - 84, 169, 140, 151, -30, 90, 77, -30, -30, -30, - -30, -30, -30, -30, -30, -30, 91, 78, -30, -30, + 96, 97, 98, 52, 99, 55, 90, 162, 62, 100, + -50, -50, 63, -50, -50, -50, -50, 91, 64, -50, + -50, 92, 107, 108, 109, 110, 154, 73, 141, 115, + 99, 161, 126, 75, 126, 111, 133, 56, 57, 83, + 84, 170, 140, 151, -30, 90, 76, -30, -30, -30, + -30, -30, -30, -30, -30, -30, 91, 77, -30, -30, 92, -30, 93, 94, 95, 96, 97, 98, 120, 99, - 128, 79, -2, 4, 100, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 83, 84, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 7, 8, 23, 10, 11, - 12, 13, 24, 80, 14, 15, 88, -81, 90, 179, - -81, -81, -81, -81, -81, -81, -81, -81, -81, 89, - 24, -81, -81, 92, -81, -81, -81, -81, -81, -81, - 116, 119, 99, 127, 122, 90, 130, 124, -72, -72, - -72, -72, -72, -72, -72, -72, 132, 138, -72, -72, - 92, 155, 158, 159, 160, 118, 123, 139, 131, 99, - 165, 145, 167, 148, 124, 73, 83, 84, 83, 84, - 173, 168, 83, 84, 149, 150, 153, 155, 84, 157, - 164, 174, 166, 170, 171, 172, 176, 177, 178, 66, - 114, 152, 85, 0, 0, 0, 0, 0, 0, 72 + 128, 78, -2, 4, 100, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 155, 79, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 56, 57, 23, 80, 58, + 116, 119, 24, 127, 59, 118, 123, 88, 131, -82, + 90, 182, -82, -82, -82, -82, -82, -82, -82, -82, + -82, 83, 84, -82, -82, 92, -82, -82, -82, -82, + -82, -82, 89, 122, 99, 130, 132, 90, 138, 124, + -73, -73, -73, -73, -73, -73, -73, -73, 139, 145, + -73, -73, 92, 7, 8, 155, 10, 11, 12, 13, + 148, 99, 14, 15, 149, 150, 124, 158, 159, 160, + 153, 84, 83, 84, 155, 166, 157, 168, 24, 73, + 83, 84, 169, 83, 84, 174, 175, 165, 167, 176, + 114, 171, 172, 173, 178, 179, 180, 181, 66, 0, + 152, 0, 85, 0, 0, 0, 0, 0, 72 }; static const yytype_int16 yycheck[] = @@ -733,23 +736,24 @@ static const yytype_int16 yycheck[] = 21, 22, 23, 30, 25, 25, 1, 146, 30, 30, 5, 6, 1, 8, 9, 10, 11, 12, 1, 14, 15, 16, 17, 18, 19, 20, 140, 30, 93, 67, - 25, 30, 70, 30, 72, 30, 28, 25, 26, 31, + 25, 145, 70, 30, 72, 30, 28, 25, 26, 31, 32, 155, 24, 108, 0, 1, 30, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 30, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 69, 25, 71, 30, 0, 1, 30, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 31, 32, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 5, 6, 25, 8, 9, - 10, 11, 30, 30, 14, 15, 30, 0, 1, 174, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 30, - 30, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 68, 69, 25, 71, 69, 1, 71, 30, 4, 5, - 6, 7, 8, 9, 10, 11, 30, 30, 14, 15, - 16, 14, 143, 144, 145, 68, 69, 30, 71, 25, - 151, 25, 153, 1, 30, 30, 31, 32, 31, 32, - 161, 30, 31, 32, 13, 30, 25, 14, 32, 30, - 30, 33, 30, 30, 30, 30, 30, 30, 30, 29, - 67, 109, 60, -1, -1, -1, -1, -1, -1, 40 + 8, 9, 10, 11, 14, 30, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 25, 26, 25, 30, 29, + 68, 69, 30, 71, 34, 68, 69, 30, 71, 0, + 1, 176, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 31, 32, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 30, 69, 25, 71, 30, 1, 30, 30, + 4, 5, 6, 7, 8, 9, 10, 11, 30, 25, + 14, 15, 16, 5, 6, 14, 8, 9, 10, 11, + 1, 25, 14, 15, 13, 30, 30, 143, 144, 145, + 25, 32, 31, 32, 14, 151, 30, 153, 30, 30, + 31, 32, 30, 31, 32, 161, 162, 30, 30, 33, + 67, 30, 30, 30, 30, 30, 30, 30, 29, -1, + 109, -1, 60, -1, -1, -1, -1, -1, 40 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -772,8 +776,9 @@ static const yytype_uint8 yystos[] = 64, 75, 30, 28, 78, 78, 79, 79, 30, 30, 24, 74, 73, 74, 78, 25, 79, 48, 1, 13, 30, 74, 73, 25, 78, 14, 77, 30, 77, 77, - 77, 79, 25, 30, 30, 77, 30, 77, 30, 78, - 30, 30, 30, 77, 33, 49, 30, 30, 30, 74 + 77, 78, 79, 25, 30, 30, 77, 30, 77, 30, + 78, 30, 30, 30, 77, 77, 33, 49, 30, 30, + 30, 30, 74 }; #define yyerrok (yyerrstatus = 0) @@ -1719,7 +1724,7 @@ yyreduce: case 41: { - menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); + menu_add_select(sym_lookup((yyvsp[(2) - (4)].string), 0), NULL, (yyvsp[(3) - (4)].expr)); printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); ;} break; @@ -1727,12 +1732,20 @@ yyreduce: case 42: { + menu_add_select(sym_lookup((yyvsp[(2) - (5)].string), 0), (yyvsp[(3) - (5)].expr), (yyvsp[(4) - (5)].expr)); + printd(DEBUG_PARSE, "%s:%d:select with value\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 43: + + { menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr)); printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); ;} break; - case 45: + case 46: { struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string))); @@ -1744,17 +1757,17 @@ yyreduce: ;} break; - case 46: + case 47: { (yyval.string) = NULL; ;} break; - case 47: + case 48: { (yyval.string) = (yyvsp[(2) - (2)].string); ;} break; - case 48: + case 49: { struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE); @@ -1765,14 +1778,14 @@ yyreduce: ;} break; - case 49: + case 50: { (yyval.menu) = menu_add_menu(); ;} break; - case 50: + case 51: { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) { @@ -1782,7 +1795,7 @@ yyreduce: ;} break; - case 58: + case 59: { menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); @@ -1790,7 +1803,7 @@ yyreduce: ;} break; - case 59: + case 60: { if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) { @@ -1803,7 +1816,7 @@ yyreduce: ;} break; - case 60: + case 61: { current_entry->sym->flags |= SYMBOL_OPTIONAL; @@ -1811,7 +1824,7 @@ yyreduce: ;} break; - case 61: + case 62: { if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) { @@ -1823,7 +1836,7 @@ yyreduce: ;} break; - case 64: + case 65: { printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); @@ -1833,7 +1846,7 @@ yyreduce: ;} break; - case 65: + case 66: { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) { @@ -1843,7 +1856,7 @@ yyreduce: ;} break; - case 71: + case 72: { menu_add_entry(NULL); @@ -1852,14 +1865,14 @@ yyreduce: ;} break; - case 72: + case 73: { (yyval.menu) = menu_add_menu(); ;} break; - case 73: + case 74: { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) { @@ -1869,7 +1882,7 @@ yyreduce: ;} break; - case 79: + case 80: { printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); @@ -1877,7 +1890,7 @@ yyreduce: ;} break; - case 80: + case 81: { menu_add_entry(NULL); @@ -1886,14 +1899,14 @@ yyreduce: ;} break; - case 81: + case 82: { menu_end_entry(); ;} break; - case 82: + case 83: { printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); @@ -1901,14 +1914,14 @@ yyreduce: ;} break; - case 83: + case 84: { current_entry->help = (yyvsp[(2) - (2)].string); ;} break; - case 88: + case 89: { menu_add_dep((yyvsp[(3) - (4)].expr)); @@ -1916,84 +1929,84 @@ yyreduce: ;} break; - case 90: + case 91: { menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr)); ;} break; - case 93: + case 94: { (yyval.id) = (yyvsp[(1) - (2)].id); ;} break; - case 94: + case 95: { (yyval.id) = (yyvsp[(1) - (2)].id); ;} break; - case 95: + case 96: { (yyval.id) = (yyvsp[(1) - (2)].id); ;} break; - case 98: + case 99: { (yyval.expr) = NULL; ;} break; - case 99: + case 100: { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;} break; - case 100: + case 101: { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;} break; - case 101: + case 102: { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} break; - case 102: + case 103: { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} break; - case 103: + case 104: { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} break; - case 104: + case 105: { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;} break; - case 105: + case 106: { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; - case 106: + case 107: { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; - case 107: + case 108: { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;} break; - case 108: + case 109: { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;} break; - case 109: + case 110: { (yyval.string) = NULL; ;} break; @@ -2387,6 +2400,15 @@ static void print_symbol(FILE *out, struct menu *menu) case P_SELECT: fputs( " select ", out); expr_fprint(prop->expr, out); + if (prop->value) { + fputs(" (value=", out); + expr_fprint(prop->value, out); + fputc(')', out); + } + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } fputc('\n', out); break; case P_RANGE: diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 23dfd3b..5f2a413 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -210,10 +210,16 @@ config_option: T_DEFAULT expr if_expr T_EOL config_option: T_SELECT T_WORD if_expr T_EOL { - menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); + menu_add_select(sym_lookup($2, 0), NULL, $3); printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); }; +config_option: T_SELECT T_WORD expr if_expr T_EOL +{ + menu_add_select(sym_lookup($2, 0), $3, $4); + printd(DEBUG_PARSE, "%s:%d:select with value\n", zconf_curname(), zconf_lineno()); +}; + config_option: T_RANGE symbol symbol if_expr T_EOL { menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); @@ -642,6 +648,15 @@ static void print_symbol(FILE *out, struct menu *menu) case P_SELECT: fputs( " select ", out); expr_fprint(prop->expr, out); + if (prop->value) { + fputs(" (value=", out); + expr_fprint(prop->value, out); + fputc(')', out); + } + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } fputc('\n', out); break; case P_RANGE: -- 1.7.1 -- Cheers, Stephen Rothwell sfr@xxxxxxxxxxxxxxxx http://www.canb.auug.org.au/~sfr/ -- To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html