aboutsummaryrefslogtreecommitdiff
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
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.
-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);