aboutsummaryrefslogtreecommitdiff
path: root/scripts/parse_kconfig
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2015-04-24 22:09:30 +0200
committerKarel Kočí <cynerd@email.cz>2015-04-24 22:09:30 +0200
commit2d9ad83a3d62ae83b3ea14266014d9b50148ad2f (patch)
treec799a36f6a0303fbd2484ba9eb60f5e20d70fc1b /scripts/parse_kconfig
parentb4b0378358fb3d46c4f483effb6ee957857b06c5 (diff)
downloadlinux-conf-perf-2d9ad83a3d62ae83b3ea14266014d9b50148ad2f.tar.gz
linux-conf-perf-2d9ad83a3d62ae83b3ea14266014d9b50148ad2f.tar.bz2
linux-conf-perf-2d9ad83a3d62ae83b3ea14266014d9b50148ad2f.zip
parse_kconfig fix wrong behaviour for non prompt symbols
Non prompt symbols should be selected always as their dependencies are satisfied. This changes adds generation of relevant rules.
Diffstat (limited to 'scripts/parse_kconfig')
-rw-r--r--scripts/parse_kconfig/cnfexpr.c82
-rw-r--r--scripts/parse_kconfig/cnfexpr.h5
-rw-r--r--scripts/parse_kconfig/output.c20
-rw-r--r--scripts/parse_kconfig/parse.c14
-rw-r--r--scripts/parse_kconfig/symlist.c7
-rw-r--r--scripts/parse_kconfig/symlist.h2
6 files changed, 109 insertions, 21 deletions
diff --git a/scripts/parse_kconfig/cnfexpr.c b/scripts/parse_kconfig/cnfexpr.c
index c9151bf..9939670 100644
--- a/scripts/parse_kconfig/cnfexpr.c
+++ b/scripts/parse_kconfig/cnfexpr.c
@@ -5,9 +5,12 @@ struct cnfexpr *cnf_eql(struct symlist *sl, bool not, struct symbol *sym1,
struct symbol *sym2);
struct cnfexpr *cnf_or(struct cnfexpr *e1, struct cnfexpr *e2);
struct cnfexpr *cnf_and(struct cnfexpr *e1, struct cnfexpr *e2);
+struct cnfexpr *cnf_not(struct cnfexpr *el);
+struct cnfexpr *cnf_copy(struct cnfexpr *el);
void free_cnf(struct cnfexpr *e);
-struct cnfexpr *kconfig_cnfexpr(struct symlist *sl, bool nt, struct expr *expr) {
+struct cnfexpr *kconfig_cnfexpr(struct symlist *sl, bool nt,
+ struct symbol *sym, struct expr *expr) {
struct stck {
struct expr *expr;
struct cnfexpr *cnf;
@@ -89,6 +92,26 @@ struct cnfexpr *kconfig_cnfexpr(struct symlist *sl, bool nt, struct expr *expr)
free(back);
free(stack);
+
+ struct symlist_el *se = symlist_find(sl, sym->name);
+ if (se->prompt || nt == true)
+ rtrn = cnf_or(cnf_sym(sl, !nt, sym), rtrn);
+ else {
+ struct cnfexpr *w12 = cnf_not(cnf_copy(rtrn));
+ struct cnfexpr *w11 = cnf_sym(sl, false, sym);
+ struct cnfexpr *w1 = cnf_or(w11, w12);
+ struct cnfexpr *w22 = rtrn;
+ struct cnfexpr *w21 = cnf_sym(sl, true, sym);
+ struct cnfexpr *w2 = cnf_or(w21, w22);
+ rtrn = cnf_and(w1, w2);
+ /*
+ rtrn =
+ cnf_and(cnf_or
+ (cnf_sym(sl, false, sym), cnf_not(cnf_copy(rtrn))),
+ cnf_or(cnf_sym(sl, true, sym), rtrn));
+ */
+ }
+
return rtrn;
}
@@ -259,6 +282,61 @@ struct cnfexpr *cnf_and(struct cnfexpr *e1, struct cnfexpr *e2) {
return e1;
}
+struct cnfexpr *cnf_not_dissolve(struct cnfexpr *expr, unsigned i) {
+ struct cnfexpr *w;
+ unsigned y;
+ w = malloc(sizeof(struct cnfexpr));
+ w->type = CT_EXPR;
+ w->size = expr->sizes[i];
+ w->exprs = malloc(w->size * sizeof(int *));
+ w->sizes = malloc(w->size * sizeof(unsigned));
+ for (y = 0; y < w->size; y++) {
+ w->sizes[y] = 1;
+ w->exprs[y] = malloc(sizeof(int));
+ w->exprs[y][0] = -1 * expr->exprs[i][y];
+ }
+ return w;
+}
+
+struct cnfexpr *cnf_not(struct cnfexpr *expr) {
+ switch (expr->type) {
+ case CT_TRUE:
+ expr->type = CT_FALSE;
+ return expr;
+ case CT_FALSE:
+ expr->type = CT_TRUE;
+ return expr;
+ case CT_EXPR:
+ break;
+ }
+ struct cnfexpr *rtrn, *w;
+ unsigned i = 0;
+ rtrn = cnf_not_dissolve(expr, 0);
+ for (i = 1; i < expr->size; i++) {
+ w = cnf_not_dissolve(expr, i);
+ rtrn = cnf_or(rtrn, w);
+ }
+ return rtrn;
+}
+
+struct cnfexpr *cnf_copy(struct cnfexpr *el) {
+ struct cnfexpr *rtrn;
+ rtrn = malloc(sizeof(struct cnfexpr));
+ rtrn->type = el->type;
+ rtrn->size = el->size;
+ if (el->type != CT_EXPR)
+ return rtrn;
+ rtrn->sizes = malloc(rtrn->size * sizeof(int));
+ memcpy(rtrn->sizes, el->sizes, rtrn->size * sizeof(int));
+ rtrn->exprs = malloc(rtrn->size * sizeof(int *));
+ unsigned i;
+ for (i = 0; i < rtrn->size; i++) {
+ rtrn->exprs[i] = malloc(rtrn->sizes[i] * sizeof(int));
+ memcpy(rtrn->exprs[i], el->exprs[i], rtrn->sizes[i] * sizeof(int));
+ }
+ return rtrn;
+}
+
void free_cnf(struct cnfexpr *e) {
if (e->type != CT_EXPR) {
free(e);
@@ -318,7 +396,7 @@ struct boolexp *printf_original(struct symlist *sl, struct expr *expr) {
case E_SYMBOL:
printf(" symbol");
if (expr->left.sym->name != NULL)
- printf(": %s", expr->left.sym->name);
+ printf(": %s", expr->left.sym->name);
printf("\n");
break;
case E_RANGE:
diff --git a/scripts/parse_kconfig/cnfexpr.h b/scripts/parse_kconfig/cnfexpr.h
index 58ac9c8..c38625a 100644
--- a/scripts/parse_kconfig/cnfexpr.h
+++ b/scripts/parse_kconfig/cnfexpr.h
@@ -12,13 +12,14 @@ enum cnfexpr_type {
};
struct cnfexpr {
- enum cnfexpr_type type;
+ enum cnfexpr_type type;
int **exprs;
unsigned *sizes;
unsigned size;
};
-struct cnfexpr *kconfig_cnfexpr(struct symlist *sl, bool nt, struct expr *expr);
+struct cnfexpr *kconfig_cnfexpr(struct symlist *sl, bool nt,
+ struct symbol *sym, struct expr *expr);
void cnf_printf(struct cnfexpr *);
struct boolexp *printf_original(struct symlist *sl, struct expr *expr);
diff --git a/scripts/parse_kconfig/output.c b/scripts/parse_kconfig/output.c
index 989f4f0..064d787 100644
--- a/scripts/parse_kconfig/output.c
+++ b/scripts/parse_kconfig/output.c
@@ -1,27 +1,23 @@
#include "output.h"
-void fprint_rules_cnf(FILE * f, unsigned id, struct cnfexpr *cnf, bool nt) {
+void fprint_rules_cnf(FILE * f, struct cnfexpr *cnf) {
unsigned i, y;
switch (cnf->type) {
case CT_FALSE:
// Never satisfiable
- if (!nt)
- fprintf(f, "-");
- fprintf(f, "%d\n", id);
- break;
+ // This should newer happen
+ fprintf(stderr,
+ "ERROR: Some rule is not satisfiable. But this should never happen.\n");
+ exit(28);
case CT_TRUE:
// Always satisfiable
break;
case CT_EXPR:
for (i = 0; i < cnf->size; i++) {
- if (!nt)
- fprintf(f, "-");
- fprintf(f, "%d ", id);
for (y = 0; y < cnf->sizes[i] - 1; y++) {
fprintf(f, "%d ", cnf->exprs[i][y]);
}
- fprintf(f, "%d ", cnf->exprs[i][cnf->sizes[i] - 1]);
- fprintf(f, "\n");
+ fprintf(f, "%d\n", cnf->exprs[i][cnf->sizes[i] - 1]);
}
break;
}
@@ -40,10 +36,10 @@ void fprint_rules(struct symlist *sl, char *output) {
if (sl->array[i].be != NULL) {
el = sl->array + i;
if (el->be != NULL) {
- fprint_rules_cnf(f, el->id, el->be, false);
+ fprint_rules_cnf(f, el->be);
}
if (el->re_be != NULL) {
- fprint_rules_cnf(f, el->id, el->re_be, true);
+ fprint_rules_cnf(f, el->re_be);
}
}
}
diff --git a/scripts/parse_kconfig/parse.c b/scripts/parse_kconfig/parse.c
index 0ac99f9..576595c 100644
--- a/scripts/parse_kconfig/parse.c
+++ b/scripts/parse_kconfig/parse.c
@@ -76,6 +76,11 @@ void build_symlist() {
symlist_add(gsymlist, sym->name);
}
}
+ struct property *prop;
+ for_all_prompts(sym, prop) {
+ gsymlist->array[gsymlist->pos - 1].prompt = true;
+ break;
+ }
}
}
@@ -84,8 +89,7 @@ void cpy_dep() {
struct symbol *sym;
struct symlist_el *el;
for_all_symbols(i, sym) {
- if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE)
- && strstr(sym->name, "NONAMEGEN") == NULL) {
+ if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE)) {
el = symlist_find(gsymlist, sym->name);
Iprintf("working: %s(%d)\n", sym->name, el->id);
@@ -93,7 +97,8 @@ void cpy_dep() {
if (verbose_level > 3)
printf_original(gsymlist, sym->dir_dep.expr);
el->be =
- kconfig_cnfexpr(gsymlist, false, sym->dir_dep.expr);
+ kconfig_cnfexpr(gsymlist, false, sym,
+ sym->dir_dep.expr);
Iprintf("Direct:\n");
if (verbose_level > 2)
cnf_printf(el->be);
@@ -103,7 +108,8 @@ void cpy_dep() {
if (verbose_level > 3)
printf_original(gsymlist, sym->rev_dep.expr);
el->re_be =
- kconfig_cnfexpr(gsymlist, true, sym->rev_dep.expr);
+ kconfig_cnfexpr(gsymlist, true, sym,
+ sym->rev_dep.expr);
Iprintf("Revers:\n");
if (verbose_level > 2)
cnf_printf(el->re_be);
diff --git a/scripts/parse_kconfig/symlist.c b/scripts/parse_kconfig/symlist.c
index a184829..c6e5140 100644
--- a/scripts/parse_kconfig/symlist.c
+++ b/scripts/parse_kconfig/symlist.c
@@ -15,12 +15,17 @@ void symlist_add(struct symlist *sl, char *name) {
sl->array =
realloc(sl->array, sl->size * sizeof(struct symlist_el));
}
- sl->array[sl->pos].id = (unsigned)sl->pos + 1;
+ sl->array[sl->pos].id = (unsigned) sl->pos + 1;
sl->array[sl->pos].name = name;
sl->array[sl->pos].be = NULL;
+ sl->array[sl->pos].prompt = false;
sl->pos++;
}
+void symlist_set_prompt(struct symlist *sl, char *name, bool prompt) {
+ symlist_find(sl, name)->prompt = prompt;
+}
+
// TODO faster implementation? Maybe binary search tree?
struct symlist_el *symlist_find(struct symlist *sl, char *name) {
size_t i = 0;
diff --git a/scripts/parse_kconfig/symlist.h b/scripts/parse_kconfig/symlist.h
index 801624c..99d9bfb 100644
--- a/scripts/parse_kconfig/symlist.h
+++ b/scripts/parse_kconfig/symlist.h
@@ -8,6 +8,7 @@
struct symlist_el {
unsigned int id;
char *name;
+ bool prompt;
struct cnfexpr *be;
struct cnfexpr *re_be; // forward dependency
};
@@ -18,6 +19,7 @@ struct symlist {
struct symlist *symlist_create();
void symlist_add(struct symlist *sl, char *name);
+void symlist_set_prompt(struct symlist *sl, char *name, bool prompt);
struct symlist_el *symlist_find(struct symlist *sl, char *name);
void symlist_print(struct symlist *sl);
void symlist_free(struct symlist *sl);