aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2015-09-12 11:46:26 +0200
committerKarel Kočí <cynerd@email.cz>2015-09-12 11:46:26 +0200
commite94207efe93141ce2d58436c56ea4271948bf148 (patch)
treee7e2ff871591f9f1c6cf363e5b6865e76ccaefa4
parent762e0304d1c493447e367a45431416fbada5cc8c (diff)
downloadlinux-conf-perf-e94207efe93141ce2d58436c56ea4271948bf148.tar.gz
linux-conf-perf-e94207efe93141ce2d58436c56ea4271948bf148.tar.bz2
linux-conf-perf-e94207efe93141ce2d58436c56ea4271948bf148.zip
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.
-rw-r--r--scripts/parse_kconfig/boolexpr.c26
-rw-r--r--scripts/parse_kconfig/boolexpr.h4
-rw-r--r--scripts/parse_kconfig/parse.c56
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();
}
}
}