diff options
Diffstat (limited to 'scripts/kconfig/symbol.c')
-rw-r--r-- | scripts/kconfig/symbol.c | 118 |
1 files changed, 87 insertions, 31 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 4a03191ad17..18f3e5c3363 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -40,7 +40,7 @@ void sym_add_default(struct symbol *sym, const char *def) { struct property *prop = prop_alloc(P_DEFAULT, sym); - prop->expr = expr_alloc_symbol(sym_lookup(def, 1)); + prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST)); } void sym_init(void) @@ -350,9 +350,6 @@ void sym_calc_value(struct symbol *sym) ; } - if (sym->flags & SYMBOL_AUTO) - sym->flags &= ~SYMBOL_WRITE; - sym->curr = newval; if (sym_is_choice(sym) && newval.tri == yes) sym->curr.val = sym_calc_choice(sym); @@ -377,6 +374,9 @@ void sym_calc_value(struct symbol *sym) sym_set_changed(choice_sym); } } + + if (sym->flags & SYMBOL_AUTO) + sym->flags &= ~SYMBOL_WRITE; } void sym_clear_all_valid(void) @@ -651,7 +651,7 @@ bool sym_is_changable(struct symbol *sym) return sym->visible > sym->rev_dep.tri; } -struct symbol *sym_lookup(const char *name, int isconst) +struct symbol *sym_lookup(const char *name, int flags) { struct symbol *symbol; const char *ptr; @@ -671,11 +671,10 @@ struct symbol *sym_lookup(const char *name, int isconst) hash &= 0xff; for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { - if (!strcmp(symbol->name, name)) { - if ((isconst && symbol->flags & SYMBOL_CONST) || - (!isconst && !(symbol->flags & SYMBOL_CONST))) - return symbol; - } + if (!strcmp(symbol->name, name) && + (flags ? symbol->flags & flags + : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) + return symbol; } new_name = strdup(name); } else { @@ -687,8 +686,7 @@ struct symbol *sym_lookup(const char *name, int isconst) memset(symbol, 0, sizeof(*symbol)); symbol->name = new_name; symbol->type = S_UNKNOWN; - if (isconst) - symbol->flags |= SYMBOL_CONST; + symbol->flags |= flags; symbol->next = symbol_hash[hash]; symbol_hash[hash] = symbol; @@ -762,8 +760,6 @@ struct symbol **sym_re_search(const char *pattern) } -struct symbol *sym_check_deps(struct symbol *sym); - static struct symbol *sym_check_expr_deps(struct expr *e) { struct symbol *sym; @@ -795,40 +791,100 @@ static struct symbol *sym_check_expr_deps(struct expr *e) } /* return NULL when dependencies are OK */ -struct symbol *sym_check_deps(struct symbol *sym) +static struct symbol *sym_check_sym_deps(struct symbol *sym) { struct symbol *sym2; struct property *prop; - if (sym->flags & SYMBOL_CHECK) { - fprintf(stderr, "%s:%d:error: found recursive dependency: %s", - sym->prop->file->name, sym->prop->lineno, sym->name); - return sym; - } - if (sym->flags & SYMBOL_CHECKED) - return NULL; - - sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); sym2 = sym_check_expr_deps(sym->rev_dep.expr); if (sym2) - goto out; + return sym2; for (prop = sym->prop; prop; prop = prop->next) { if (prop->type == P_CHOICE || prop->type == P_SELECT) continue; sym2 = sym_check_expr_deps(prop->visible.expr); if (sym2) - goto out; + break; if (prop->type != P_DEFAULT || sym_is_choice(sym)) continue; sym2 = sym_check_expr_deps(prop->expr); if (sym2) - goto out; + break; } -out: + + return sym2; +} + +static struct symbol *sym_check_choice_deps(struct symbol *choice) +{ + struct symbol *sym, *sym2; + struct property *prop; + struct expr *e; + + prop = sym_get_choice_prop(choice); + expr_list_for_each_sym(prop->expr, e, sym) + sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); + + choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); + sym2 = sym_check_sym_deps(choice); + choice->flags &= ~SYMBOL_CHECK; if (sym2) - fprintf(stderr, " -> %s%s", sym->name, sym2 == sym? "\n": ""); - sym->flags &= ~SYMBOL_CHECK; + goto out; + + expr_list_for_each_sym(prop->expr, e, sym) { + sym2 = sym_check_sym_deps(sym); + if (sym2) { + fprintf(stderr, " -> %s", sym->name); + break; + } + } +out: + expr_list_for_each_sym(prop->expr, e, sym) + sym->flags &= ~SYMBOL_CHECK; + + if (sym2 && sym_is_choice_value(sym2) && + prop_get_symbol(sym_get_choice_prop(sym2)) == choice) + sym2 = choice; + + return sym2; +} + +struct symbol *sym_check_deps(struct symbol *sym) +{ + struct symbol *sym2; + struct property *prop; + + if (sym->flags & SYMBOL_CHECK) { + fprintf(stderr, "%s:%d:error: found recursive dependency: %s", + sym->prop->file->name, sym->prop->lineno, + sym->name ? sym->name : "<choice>"); + return sym; + } + if (sym->flags & SYMBOL_CHECKED) + return NULL; + + if (sym_is_choice_value(sym)) { + /* for choice groups start the check with main choice symbol */ + prop = sym_get_choice_prop(sym); + sym2 = sym_check_deps(prop_get_symbol(prop)); + } else if (sym_is_choice(sym)) { + sym2 = sym_check_choice_deps(sym); + } else { + sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); + sym2 = sym_check_sym_deps(sym); + sym->flags &= ~SYMBOL_CHECK; + } + + if (sym2) { + fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); + if (sym2 == sym) { + fprintf(stderr, "\n"); + zconfnerrs++; + sym2 = NULL; + } + } + return sym2; } @@ -904,7 +960,7 @@ void prop_add_env(const char *env) } prop = prop_alloc(P_ENV, sym); - prop->expr = expr_alloc_symbol(sym_lookup(env, 1)); + prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST)); sym_env_list = expr_alloc_one(E_LIST, sym_env_list); sym_env_list->right.sym = sym; |