Skip to content

Commit 5a1aa8a

Browse files
Roman ZippelSam Ravnborg
Roman Zippel
authored and
Sam Ravnborg
committed
kconfig: add named choice group
As choice dependency are now fully checked, it's quite easy to add support for named choices. This lifts the restriction that a choice value can only appear once, although it still has to be within the same group, but multiple choices can be joined by giving them a name. While at it I cleaned up a little the choice type logic to simplify it a bit. Signed-off-by: Roman Zippel <[email protected]> Signed-off-by: Sam Ravnborg <[email protected]>
1 parent 4898117 commit 5a1aa8a

File tree

6 files changed

+206
-223
lines changed

6 files changed

+206
-223
lines changed

scripts/kconfig/lex.zconf.c_shipped

+3-22
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,6 @@
55

66
/* A lexical scanner generated by flex */
77

8-
#define yy_create_buffer zconf_create_buffer
9-
#define yy_delete_buffer zconf_delete_buffer
10-
#define yy_flex_debug zconf_flex_debug
11-
#define yy_init_buffer zconf_init_buffer
12-
#define yy_flush_buffer zconf_flush_buffer
13-
#define yy_load_buffer_state zconf_load_buffer_state
14-
#define yy_switch_to_buffer zconf_switch_to_buffer
15-
#define yyin zconfin
16-
#define yyleng zconfleng
17-
#define yylex zconflex
18-
#define yylineno zconflineno
19-
#define yyout zconfout
20-
#define yyrestart zconfrestart
21-
#define yytext zconftext
22-
#define yywrap zconfwrap
23-
#define yyalloc zconfalloc
24-
#define yyrealloc zconfrealloc
25-
#define yyfree zconffree
26-
278
#define FLEX_SCANNER
289
#define YY_FLEX_MAJOR_VERSION 2
2910
#define YY_FLEX_MINOR_VERSION 5
@@ -354,7 +335,7 @@ void zconffree (void * );
354335

355336
/* Begin user sect3 */
356337

357-
#define zconfwrap(n) 1
338+
#define zconfwrap() 1
358339
#define YY_SKIP_YYWRAP
359340

360341
typedef unsigned char YY_CHAR;
@@ -1535,7 +1516,7 @@ static int yy_get_next_buffer (void)
15351516

15361517
/* Read in more data. */
15371518
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
1538-
(yy_n_chars), num_to_read );
1519+
(yy_n_chars), (size_t) num_to_read );
15391520

15401521
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
15411522
}
@@ -2007,7 +1988,7 @@ YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
20071988

20081989
/** Setup the input buffer state to scan a string. The next call to zconflex() will
20091990
* scan from a @e copy of @a str.
2010-
* @param str a NUL-terminated string to scan
1991+
* @param yystr a NUL-terminated string to scan
20111992
*
20121993
* @return the newly allocated buffer state object.
20131994
* @note If you want to scan bytes that may contain NUL values, then use

scripts/kconfig/lkc_proto.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ P(menu_get_help,const char *,(struct menu *menu));
2121
/* symbol.c */
2222
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
2323

24-
P(sym_lookup,struct symbol *,(const char *name, int isconst));
24+
P(sym_lookup,struct symbol *,(const char *name, int flags));
2525
P(sym_find,struct symbol *,(const char *name));
2626
P(sym_re_search,struct symbol **,(const char *pattern));
2727
P(sym_type_name,const char *,(enum symbol_type type));

scripts/kconfig/menu.c

+27-37
Original file line numberDiff line numberDiff line change
@@ -235,18 +235,22 @@ void menu_finalize(struct menu *parent)
235235
sym = parent->sym;
236236
if (parent->list) {
237237
if (sym && sym_is_choice(sym)) {
238-
/* find the first choice value and find out choice type */
239-
for (menu = parent->list; menu; menu = menu->next) {
240-
if (menu->sym) {
241-
current_entry = parent;
242-
if (sym->type == S_UNKNOWN)
238+
if (sym->type == S_UNKNOWN) {
239+
/* find the first choice value to find out choice type */
240+
current_entry = parent;
241+
for (menu = parent->list; menu; menu = menu->next) {
242+
if (menu->sym && menu->sym->type != S_UNKNOWN) {
243243
menu_set_type(menu->sym->type);
244-
current_entry = menu;
245-
if (menu->sym->type == S_UNKNOWN)
246-
menu_set_type(sym->type);
247-
break;
244+
break;
245+
}
248246
}
249247
}
248+
/* set the type of the remaining choice values */
249+
for (menu = parent->list; menu; menu = menu->next) {
250+
current_entry = menu;
251+
if (menu->sym && menu->sym->type == S_UNKNOWN)
252+
menu_set_type(sym->type);
253+
}
250254
parentdep = expr_alloc_symbol(sym);
251255
} else if (parent->prompt)
252256
parentdep = parent->prompt->visible.expr;
@@ -313,50 +317,36 @@ void menu_finalize(struct menu *parent)
313317
}
314318
}
315319
for (menu = parent->list; menu; menu = menu->next) {
316-
if (sym && sym_is_choice(sym) && menu->sym) {
320+
if (sym && sym_is_choice(sym) &&
321+
menu->sym && !sym_is_choice_value(menu->sym)) {
322+
current_entry = menu;
317323
menu->sym->flags |= SYMBOL_CHOICEVAL;
318324
if (!menu->prompt)
319325
menu_warn(menu, "choice value must have a prompt");
320326
for (prop = menu->sym->prop; prop; prop = prop->next) {
321-
if (prop->type == P_PROMPT && prop->menu != menu) {
322-
prop_warn(prop, "choice values "
323-
"currently only support a "
324-
"single prompt");
325-
}
326327
if (prop->type == P_DEFAULT)
327328
prop_warn(prop, "defaults for choice "
328-
"values not supported");
329+
"values not supported");
330+
if (prop->menu == menu)
331+
continue;
332+
if (prop->type == P_PROMPT &&
333+
prop->menu->parent->sym != sym)
334+
prop_warn(prop, "choice value used outside its choice group");
329335
}
330-
current_entry = menu;
331-
if (menu->sym->type == S_UNKNOWN)
332-
menu_set_type(sym->type);
333336
/* Non-tristate choice values of tristate choices must
334337
* depend on the choice being set to Y. The choice
335338
* values' dependencies were propagated to their
336339
* properties above, so the change here must be re-
337-
* propagated. */
340+
* propagated.
341+
*/
338342
if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) {
339343
basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
340-
basedep = expr_alloc_and(basedep, menu->dep);
341-
basedep = expr_eliminate_dups(basedep);
342-
menu->dep = basedep;
344+
menu->dep = expr_alloc_and(basedep, menu->dep);
343345
for (prop = menu->sym->prop; prop; prop = prop->next) {
344346
if (prop->menu != menu)
345347
continue;
346-
dep = expr_alloc_and(expr_copy(basedep),
347-
prop->visible.expr);
348-
dep = expr_eliminate_dups(dep);
349-
dep = expr_trans_bool(dep);
350-
prop->visible.expr = dep;
351-
if (prop->type == P_SELECT) {
352-
struct symbol *es = prop_get_symbol(prop);
353-
dep2 = expr_alloc_symbol(menu->sym);
354-
dep = expr_alloc_and(dep2,
355-
expr_copy(dep));
356-
dep = expr_alloc_or(es->rev_dep.expr, dep);
357-
dep = expr_eliminate_dups(dep);
358-
es->rev_dep.expr = dep;
359-
}
348+
prop->visible.expr = expr_alloc_and(expr_copy(basedep),
349+
prop->visible.expr);
360350
}
361351
}
362352
menu_add_symbol(P_CHOICE, sym, NULL);

scripts/kconfig/symbol.c

+11-13
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void sym_add_default(struct symbol *sym, const char *def)
4040
{
4141
struct property *prop = prop_alloc(P_DEFAULT, sym);
4242

43-
prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
43+
prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
4444
}
4545

4646
void sym_init(void)
@@ -350,9 +350,6 @@ void sym_calc_value(struct symbol *sym)
350350
;
351351
}
352352

353-
if (sym->flags & SYMBOL_AUTO)
354-
sym->flags &= ~SYMBOL_WRITE;
355-
356353
sym->curr = newval;
357354
if (sym_is_choice(sym) && newval.tri == yes)
358355
sym->curr.val = sym_calc_choice(sym);
@@ -377,6 +374,9 @@ void sym_calc_value(struct symbol *sym)
377374
sym_set_changed(choice_sym);
378375
}
379376
}
377+
378+
if (sym->flags & SYMBOL_AUTO)
379+
sym->flags &= ~SYMBOL_WRITE;
380380
}
381381

382382
void sym_clear_all_valid(void)
@@ -651,7 +651,7 @@ bool sym_is_changable(struct symbol *sym)
651651
return sym->visible > sym->rev_dep.tri;
652652
}
653653

654-
struct symbol *sym_lookup(const char *name, int isconst)
654+
struct symbol *sym_lookup(const char *name, int flags)
655655
{
656656
struct symbol *symbol;
657657
const char *ptr;
@@ -671,11 +671,10 @@ struct symbol *sym_lookup(const char *name, int isconst)
671671
hash &= 0xff;
672672

673673
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
674-
if (!strcmp(symbol->name, name)) {
675-
if ((isconst && symbol->flags & SYMBOL_CONST) ||
676-
(!isconst && !(symbol->flags & SYMBOL_CONST)))
677-
return symbol;
678-
}
674+
if (!strcmp(symbol->name, name) &&
675+
(flags ? symbol->flags & flags
676+
: !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
677+
return symbol;
679678
}
680679
new_name = strdup(name);
681680
} else {
@@ -687,8 +686,7 @@ struct symbol *sym_lookup(const char *name, int isconst)
687686
memset(symbol, 0, sizeof(*symbol));
688687
symbol->name = new_name;
689688
symbol->type = S_UNKNOWN;
690-
if (isconst)
691-
symbol->flags |= SYMBOL_CONST;
689+
symbol->flags |= flags;
692690

693691
symbol->next = symbol_hash[hash];
694692
symbol_hash[hash] = symbol;
@@ -962,7 +960,7 @@ void prop_add_env(const char *env)
962960
}
963961

964962
prop = prop_alloc(P_ENV, sym);
965-
prop->expr = expr_alloc_symbol(sym_lookup(env, 1));
963+
prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
966964

967965
sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
968966
sym_env_list->right.sym = sym;

0 commit comments

Comments
 (0)