From d837647515b59137a837c3f67dacfc9b7ad3e981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Mon, 4 May 2015 20:19:57 +0200 Subject: parse_kconfig adding proper visibility dependency For unknown reasons, output rules with generated default solution are not satisfiable. --- scripts/parse_kconfig/boolexpr.c | 40 ++++++----- scripts/parse_kconfig/boolexpr.h | 6 +- scripts/parse_kconfig/parse.c | 147 +++++++++++++++++++++++++++++---------- scripts/parse_kconfig/symlist.c | 2 +- scripts/parse_kconfig/symlist.h | 7 +- 5 files changed, 140 insertions(+), 62 deletions(-) (limited to 'scripts/parse_kconfig') diff --git a/scripts/parse_kconfig/boolexpr.c b/scripts/parse_kconfig/boolexpr.c index 4ce4154..4d58654 100644 --- a/scripts/parse_kconfig/boolexpr.c +++ b/scripts/parse_kconfig/boolexpr.c @@ -3,7 +3,8 @@ struct boolexpr *boolexpr_eql(struct symlist *sl, struct symbol *sym1, struct symbol *sym2); -struct boolexpr *boolexpr_kconfig(struct symlist *sl, struct expr *expr) { +struct boolexpr *boolexpr_kconfig(struct symlist *sl, struct expr *expr, + bool modulesym) { struct stck { struct expr *expr; struct boolexpr *bl; @@ -29,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); + rtn = boolexpr_sym(sl, expr->left.sym, modulesym); goto go_up; case E_NOT: if (rtn == NULL) @@ -109,14 +110,20 @@ struct boolexpr *boolexpr_false() { return rtn; } -struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym) { +struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym, + bool modulesym) { struct boolexpr *rtn; rtn = malloc(sizeof(struct boolexpr)); rtn->overusage = 0; - if (!strcmp(sym->name, "m") || !strcmp(sym->name, "n")) { + if (!strcmp(sym->name, "m")) { + if (modulesym) + rtn->type = BT_TRUE; + else rtn->type = BT_FALSE; + } else if (!strcmp(sym->name, "n")) { + rtn->type = BT_FALSE; } else if (!strcmp(sym->name, "y")) { - rtn->type = BT_TRUE; + rtn->type = BT_TRUE; } else { rtn->id = symlist_id(sl, sym->name); if (rtn->id != 0) @@ -127,8 +134,8 @@ struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym) { return rtn; } -struct boolexpr *boolexpr_eql(struct symlist *sl, struct symbol *sym1, - struct symbol *sym2) { +struct boolexpr *boolexpr_eql(struct symlist *sl, + struct symbol *sym1, struct symbol *sym2) { if (!strcmp(sym2->name, "m")) { struct boolexpr *rtn = malloc(sizeof(struct boolexpr)); rtn->overusage = 0; @@ -137,20 +144,18 @@ struct boolexpr *boolexpr_eql(struct symlist *sl, struct symbol *sym1, return rtn; } if (!strcmp(sym2->name, "n")) - return boolexpr_not(boolexpr_sym(sl, sym1)); + return boolexpr_not(boolexpr_sym(sl, sym1, false)); if (!strcmp(sym2->name, "y")) - return boolexpr_sym(sl, sym1); - + return boolexpr_sym(sl, sym1, false); // sym1 <-> sym2 // (!sym1 || sym2) && (sym1 || !sym2) return boolexpr_and(boolexpr_or - (boolexpr_not(boolexpr_sym(sl, sym1)), - boolexpr_sym(sl, sym2)), boolexpr_or(boolexpr_sym(sl, - sym1), - boolexpr_not - (boolexpr_sym - (sl, sym2)))); + (boolexpr_not(boolexpr_sym(sl, sym1, false)), + boolexpr_sym(sl, sym2, false)), + boolexpr_or(boolexpr_sym(sl, sym1, false), + boolexpr_not(boolexpr_sym + (sl, sym2, false)))); } struct boolexpr *boolexpr_or(struct boolexpr *e1, struct boolexpr *e2) { @@ -222,7 +227,6 @@ struct boolexpr *boolexpr_not(struct boolexpr *e) { rtn = malloc(sizeof(struct boolexpr)); rtn->overusage = 0; rtn->id = 0; - switch (e->type) { case BT_FALSE: rtn->type = BT_TRUE; @@ -244,7 +248,6 @@ void boolexpr_free(struct boolexpr *e) { struct boolexpr **stack; size_t stack_size = 2, stack_pos = 0; stack = malloc(stack_size * sizeof(struct boolexpr *)); - struct boolexpr *m; while (e != NULL) { m = e; @@ -278,7 +281,6 @@ struct boolexpr *boolexpr_copy(struct boolexpr *e) { struct boolexpr **stack; size_t stack_size = 2, stack_pos = 0; stack = malloc(stack_size * sizeof(struct boolexpr *)); - while (e != NULL) { e->overusage++; switch (e->type) { diff --git a/scripts/parse_kconfig/boolexpr.h b/scripts/parse_kconfig/boolexpr.h index 52cd4a6..5a368bf 100644 --- a/scripts/parse_kconfig/boolexpr.h +++ b/scripts/parse_kconfig/boolexpr.h @@ -20,11 +20,13 @@ struct boolexpr { unsigned overusage; }; -struct boolexpr *boolexpr_kconfig(struct symlist *sl, struct expr *expr); +struct boolexpr *boolexpr_kconfig(struct symlist *sl, struct expr *expr, + bool modulesym); struct boolexpr *boolexpr_true(); struct boolexpr *boolexpr_false(); -struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym); +struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym, + bool modulesym); 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 54941dc..b7ab951 100644 --- a/scripts/parse_kconfig/parse.c +++ b/scripts/parse_kconfig/parse.c @@ -84,16 +84,12 @@ void build_symlist() { } symlist_add(gsymlist, sym->name); } - for_all_prompts(sym, prop) { - gsymlist->array[gsymlist->pos - 1].prompt = true; - break; - } } symlist_closesym(gsymlist); } void cpy_dep() { - int i; + int i, y; struct symbol *sym; struct property *prop; struct symlist_el *el; @@ -103,14 +99,39 @@ void cpy_dep() { el_id = symlist_id(gsymlist, sym->name); el = &(gsymlist->array[el_id - 1]); Iprintf("Processing: %s\n", sym->name); - if (el->prompt) - Dprintf("Is prompt\n"); - + // Visibility + for_all_prompts(sym, prop) { + Dprintf(" Prompt: %s\n", prop->text); + if (prop->visible.expr != NULL) { + doutput_expr(prop->visible.expr); + struct boolexpr *vis = + boolexpr_kconfig(gsymlist, prop->visible.expr, false); + if (el->vis == NULL) { + el->vis = vis; + } else { + el->vis = boolexpr_or(el->vis, vis); + } + } + } + if (el->vis == NULL) + el->vis = boolexpr_false(); + // Symbol is choice.. special treatment required + if (sym_is_choice(sym)) { + Dprintf(" Is Choice\n"); + goto choice_exception; + } + // Default value for_all_defaults(sym, prop) { Dprintf(" Default value:\n"); doutput_expr(prop->expr); struct boolexpr *def = - boolexpr_kconfig(gsymlist, prop->expr); + boolexpr_kconfig(gsymlist, prop->expr, false); + if (prop->visible.expr != NULL) + def = + boolexpr_and(def, + boolexpr_kconfig(gsymlist, + prop->visible.expr, + false)); if (el->def == NULL) { el->def = def; } else { @@ -119,50 +140,102 @@ void cpy_dep() { } if (el->def == NULL) el->def = boolexpr_false(); + // Dependency expression if (sym->dir_dep.expr != NULL) { Dprintf(" Dependency:\n"); doutput_expr(sym->dir_dep.expr); - el->dep = boolexpr_kconfig(gsymlist, sym->dir_dep.expr); + el->dep = + boolexpr_kconfig(gsymlist, sym->dir_dep.expr, false); } else el->dep = boolexpr_true(); + // Reverse dependency expression if (sym->rev_dep.expr != NULL) { Dprintf(" Reverse dependency:\n"); doutput_expr(sym->rev_dep.expr); el->rev_dep = - boolexpr_kconfig(gsymlist, sym->rev_dep.expr); + boolexpr_kconfig(gsymlist, sym->rev_dep.expr, false); } else el->rev_dep = boolexpr_false(); + choice_exception: + // Add exclusive rules for choice symbol + if (sym_is_choice(sym)) { + el->def = boolexpr_true(); + if (sym->dir_dep.expr != NULL) { + Dprintf(" Reverse dependency:\n"); + doutput_expr(sym->dir_dep.expr); + el->rev_dep = + boolexpr_kconfig(gsymlist, + sym->dir_dep.expr, true); + } else + el->rev_dep = boolexpr_false(); + if (sym->rev_dep.expr != NULL) { + Dprintf(" Dependency:\n"); + doutput_expr(sym->rev_dep.expr); + el->dep = + boolexpr_kconfig(gsymlist, + sym->rev_dep.expr, true); + } else + el->dep = boolexpr_true(); + for_all_choices(sym, prop) { + struct symbol *symw; + struct expr *exprw; + unsigned *symx = NULL; + size_t symx_size; + symx_size = 0; + expr_list_for_each_sym(prop->expr, exprw, symw) { + symx_size++; + symx = realloc(symx, symx_size * sizeof(unsigned)); + symx[symx_size - 1] = + symlist_id(gsymlist, symw->name); + output_rules_symbol(symx[symx_size - 1]); + } + output_rules_symbol(-(int) + el_id); + output_rules_endterm(); + for (i = 0; i < symx_size - 1; i++) { + for (y = i + 1; y < symx_size; y++) { + output_rules_symbol(-(int) + symx[i]); + output_rules_symbol(-(int) + symx[y]); + output_rules_endterm(); + } + } + free(symx); + symx = NULL; + } + } struct boolexpr *pw; - struct boolexpr *boolsym = boolexpr_sym(gsymlist, sym); + struct boolexpr *boolsym = boolexpr_sym(gsymlist, sym, + false); boolexpr_copy(boolsym); struct boolexpr *boolsym_not = boolexpr_not(boolsym); - if (!el->prompt) { - boolexpr_copy(boolsym); - boolexpr_copy(boolsym_not); - boolexpr_copy(el->def); - boolexpr_copy(el->dep); - boolexpr_copy(el->rev_dep); - } - // (!sym || dep) && (sym || !rev_dep) - struct boolexpr *w1 = boolexpr_or(boolsym_not, el->dep); - struct boolexpr *w2 = - boolexpr_or(boolsym, boolexpr_not(el->rev_dep)); - pw = boolexpr_and(w1, w2); + boolexpr_copy(boolsym); + boolexpr_copy(boolsym_not); + boolexpr_copy(el->vis); + boolexpr_copy(el->def); + boolexpr_copy(el->dep); + boolexpr_copy(el->rev_dep); + // (!sym || dep) && (sym || !rev_dep) && + // && (sym || !dep || !def || vis) && + // (!sym || rev_dep || def || vis) + struct boolexpr *w1 = boolexpr_or(boolsym_not, + el->dep); + struct boolexpr *w2 = boolexpr_or(boolsym, + boolexpr_not(el->rev_dep)); + struct boolexpr *w3 = boolexpr_or(boolsym, + boolexpr_not(el->dep)); + w3 = boolexpr_or(w3, boolexpr_not(el->def)); + w3 = boolexpr_or(w3, el->vis); + struct boolexpr *w4 = boolexpr_or(boolsym_not, + el->rev_dep); + w4 = boolexpr_or(w4, el->def); + w4 = boolexpr_or(w4, el->vis); - if (!el->prompt) { - // && (sym || !dep || !def) && - // (!sym || rev_dep || def) - struct boolexpr *w31 = - boolexpr_or(boolsym, boolexpr_not(el->dep)); - struct boolexpr *w3 = - boolexpr_or(w31, boolexpr_not(el->def)); - struct boolexpr *w41 = - boolexpr_or(boolsym_not, el->rev_dep); - struct boolexpr *w4 = boolexpr_or(w41, el->def); - pw = boolexpr_and(pw, w3); - pw = boolexpr_and(pw, w4); - } + pw = boolexpr_and(w1, w2); + pw = boolexpr_and(pw, w3); + pw = boolexpr_and(pw, w4); Dprintf(" CNF:\n"); doutput_boolexpr(pw, gsymlist); cnf_boolexpr(gsymlist, pw); diff --git a/scripts/parse_kconfig/symlist.c b/scripts/parse_kconfig/symlist.c index d38dde1..f81facf 100644 --- a/scripts/parse_kconfig/symlist.c +++ b/scripts/parse_kconfig/symlist.c @@ -17,8 +17,8 @@ void symlist_add(struct symlist *sl, char *name) { realloc(sl->array, sl->size * sizeof(struct symlist_el)); } sl->array[sl->pos].name = name; - sl->array[sl->pos].prompt = false; sl->array[sl->pos].def = NULL; + sl->array[sl->pos].vis = NULL; sl->array[sl->pos].dep = NULL; sl->array[sl->pos].rev_dep = NULL; output_push_symbol((unsigned) sl->pos + 1, name); diff --git a/scripts/parse_kconfig/symlist.h b/scripts/parse_kconfig/symlist.h index 234f776..5499bff 100644 --- a/scripts/parse_kconfig/symlist.h +++ b/scripts/parse_kconfig/symlist.h @@ -12,9 +12,10 @@ struct symlist_el { char *name; - bool prompt; - - struct boolexpr *def, *dep, *rev_dep; + struct boolexpr *def; // default value + struct boolexpr *vis; // visibility + struct boolexpr *dep; // direct dependency + struct boolexpr *rev_dep; // reverse dependency }; struct symlist { -- cgit v1.2.3