aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/parse_kconfig/boolexpr.c40
-rw-r--r--scripts/parse_kconfig/boolexpr.h6
-rw-r--r--scripts/parse_kconfig/parse.c147
-rw-r--r--scripts/parse_kconfig/symlist.c2
-rw-r--r--scripts/parse_kconfig/symlist.h7
5 files changed, 140 insertions, 62 deletions
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 {