From e94207efe93141ce2d58436c56ea4271948bf148 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Sat, 12 Sep 2015 11:46:26 +0200 Subject: [PATCH] Fix parse_kconfig choice parsing Parsing choices was implemented wrong. For non-optional choice output rules must contain also dependency of all choice symbols. Because if no choice symbol has fulfilled dependencies, than choice shouldn't be selected. --- scripts/parse_kconfig/boolexpr.c | 26 ++++++++++----- scripts/parse_kconfig/boolexpr.h | 4 +-- scripts/parse_kconfig/parse.c | 56 ++++++++++++++++++++++---------- 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/scripts/parse_kconfig/boolexpr.c b/scripts/parse_kconfig/boolexpr.c index 4d58654..b6f008d 100644 --- a/scripts/parse_kconfig/boolexpr.c +++ b/scripts/parse_kconfig/boolexpr.c @@ -4,7 +4,7 @@ struct boolexpr *boolexpr_eql(struct symlist *sl, struct symbol *sym1, struct symbol *sym2); struct boolexpr *boolexpr_kconfig(struct symlist *sl, struct expr *expr, - bool modulesym) { + bool modulesym, struct symbol **as_true) { struct stck { struct expr *expr; struct boolexpr *bl; @@ -30,7 +30,7 @@ struct boolexpr *boolexpr_kconfig(struct symlist *sl, struct expr *expr, } switch (expr->type) { case E_SYMBOL: - rtn = boolexpr_sym(sl, expr->left.sym, modulesym); + rtn = boolexpr_sym(sl, expr->left.sym, modulesym, as_true); goto go_up; case E_NOT: if (rtn == NULL) @@ -111,7 +111,7 @@ struct boolexpr *boolexpr_false() { } struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym, - bool modulesym) { + bool modulesym, struct symbol **as_true) { struct boolexpr *rtn; rtn = malloc(sizeof(struct boolexpr)); rtn->overusage = 0; @@ -125,6 +125,14 @@ struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym, } else if (!strcmp(sym->name, "y")) { rtn->type = BT_TRUE; } else { + if (as_true != NULL) { + for (; *as_true != NULL; as_true++) { + if (!strcmp((*as_true)->name, sym->name)) { + rtn->type = BT_TRUE; + return rtn; + } + } + } rtn->id = symlist_id(sl, sym->name); if (rtn->id != 0) rtn->type = BT_SYM; @@ -144,18 +152,18 @@ struct boolexpr *boolexpr_eql(struct symlist *sl, return rtn; } if (!strcmp(sym2->name, "n")) - return boolexpr_not(boolexpr_sym(sl, sym1, false)); + return boolexpr_not(boolexpr_sym(sl, sym1, false, NULL)); if (!strcmp(sym2->name, "y")) - return boolexpr_sym(sl, sym1, false); + return boolexpr_sym(sl, sym1, false, NULL); // sym1 <-> sym2 // (!sym1 || sym2) && (sym1 || !sym2) return boolexpr_and(boolexpr_or - (boolexpr_not(boolexpr_sym(sl, sym1, false)), - boolexpr_sym(sl, sym2, false)), - boolexpr_or(boolexpr_sym(sl, sym1, false), + (boolexpr_not(boolexpr_sym(sl, sym1, false, NULL)), + boolexpr_sym(sl, sym2, false, NULL)), + boolexpr_or(boolexpr_sym(sl, sym1, false, NULL), boolexpr_not(boolexpr_sym - (sl, sym2, false)))); + (sl, sym2, false, NULL)))); } struct boolexpr *boolexpr_or(struct boolexpr *e1, struct boolexpr *e2) { diff --git a/scripts/parse_kconfig/boolexpr.h b/scripts/parse_kconfig/boolexpr.h index 5a368bf..5eeb3f8 100644 --- a/scripts/parse_kconfig/boolexpr.h +++ b/scripts/parse_kconfig/boolexpr.h @@ -21,12 +21,12 @@ struct boolexpr { }; struct boolexpr *boolexpr_kconfig(struct symlist *sl, struct expr *expr, - bool modulesym); + bool modulesym, struct symbol **as_true); struct boolexpr *boolexpr_true(); struct boolexpr *boolexpr_false(); struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym, - bool modulesym); + bool modulesym, struct symbol **as_true); struct boolexpr *boolexpr_or(struct boolexpr *e1, struct boolexpr *e2); struct boolexpr *boolexpr_and(struct boolexpr *e1, struct boolexpr *e2); struct boolexpr *boolexpr_not(struct boolexpr *e); diff --git a/scripts/parse_kconfig/parse.c b/scripts/parse_kconfig/parse.c index 9b6c1cb..9de456f 100644 --- a/scripts/parse_kconfig/parse.c +++ b/scripts/parse_kconfig/parse.c @@ -99,7 +99,7 @@ void cpy_dep() { if (sym->type == S_BOOLEAN || sym->type == S_TRISTATE) { el_id = symlist_id(gsymlist, sym->name); el = &(gsymlist->array[el_id - 1]); - boolsym = boolexpr_sym(gsymlist, sym, false); + boolsym = boolexpr_sym(gsymlist, sym, false, NULL); Iprintf("Processing: %s\n", sym->name); // Visibility for_all_prompts(sym, prop) { @@ -108,7 +108,7 @@ void cpy_dep() { doutput_expr(prop->visible.expr); struct boolexpr *vis = boolexpr_kconfig(gsymlist, prop->visible.expr, - false); + false, NULL); if (el->vis == NULL) { el->vis = vis; } else { @@ -130,13 +130,13 @@ void cpy_dep() { Dprintf(" Default value:\n"); doutput_expr(prop->expr); struct boolexpr *def = - boolexpr_kconfig(gsymlist, prop->expr, true); + boolexpr_kconfig(gsymlist, prop->expr, true, NULL); if (prop->visible.expr != NULL) def = boolexpr_and(def, boolexpr_kconfig(gsymlist, prop->visible.expr, - false)); + false, NULL)); if (el->def == NULL) { el->def = def; } else { @@ -150,7 +150,7 @@ void cpy_dep() { Dprintf(" Dependency:\n"); doutput_expr(sym->dir_dep.expr); el->dep = - boolexpr_kconfig(gsymlist, sym->dir_dep.expr, false); + boolexpr_kconfig(gsymlist, sym->dir_dep.expr, false, NULL); } else el->dep = boolexpr_true(); // Reverse dependency expression @@ -158,7 +158,7 @@ void cpy_dep() { Dprintf(" Reverse dependency:\n"); doutput_expr(sym->rev_dep.expr); el->rev_dep = - boolexpr_kconfig(gsymlist, sym->rev_dep.expr, false); + boolexpr_kconfig(gsymlist, sym->rev_dep.expr, false, NULL); } else el->rev_dep = boolexpr_false(); @@ -230,7 +230,7 @@ void cpy_dep() { Dprintf(" Dependency:\n"); doutput_expr(sym->rev_dep.expr); el->rev_dep = - boolexpr_kconfig(gsymlist, sym->rev_dep.expr, true); + boolexpr_kconfig(gsymlist, sym->rev_dep.expr, true, NULL); } else el->rev_dep = boolexpr_true(); for_all_choices(sym, prop) { @@ -265,8 +265,8 @@ void cpy_dep() { if (el->vis->type != BT_FALSE && el->vis->type != BT_TRUE) cnf_boolexpr(gsymlist, el->vis); // (!sym || rev_dep) && (!sym || !rev_dep || vis) - // For nonoptional add: - // (sym || !rev_dep || !vis) + // For nonoptional per list symbol add: + // (sym || !rev_dep || !vis || !dir_dep_of_list)) if (el->rev_dep->type != BT_TRUE) { output_rules_symbol(-1 * boolsym->id); if (el->rev_dep->type != BT_FALSE) { @@ -285,16 +285,36 @@ void cpy_dep() { output_rules_endterm(); } if (!sym_is_optional(sym)) { - if (el->rev_dep->type != BT_FALSE - && el->vis->type != BT_FALSE) { - output_rules_symbol(boolsym->id); - if (el->rev_dep->type != BT_TRUE) { - output_rules_symbol(-1 * el->rev_dep->id); + for_all_choices(sym, prop) { + struct symbol *symw; + struct expr *exprw; + expr_list_for_each_sym(prop->expr, exprw, symw) { + struct boolexpr *wdep; + if (symw->dir_dep.expr != NULL) { + struct symbol *settrue[] = {sym, NULL}; + wdep = + boolexpr_kconfig(gsymlist, symw->dir_dep.expr, + false, settrue); + } else + wdep = boolexpr_true(); + cnf_boolexpr(gsymlist, wdep); + if (el->rev_dep->type != BT_FALSE + && el->vis->type != BT_FALSE + && wdep->type != BT_FALSE) { + output_rules_symbol(boolsym->id); + if (el->rev_dep->type != BT_TRUE) { + output_rules_symbol(-1 * el->rev_dep->id); + } + if (el->vis->type != BT_TRUE) { + output_rules_symbol(-1 * el->vis->id); + } + if (wdep->type != BT_TRUE + && wdep->id != boolsym->id) { + output_rules_symbol(-1 * wdep->id); + } + output_rules_endterm(); + } } - if (el->vis->type != BT_TRUE) { - output_rules_symbol(-1 * el->vis->id); - } - output_rules_endterm(); } } } -- 2.39.2