From 2d9ad83a3d62ae83b3ea14266014d9b50148ad2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Fri, 24 Apr 2015 22:09:30 +0200 Subject: 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. --- scripts/parse_kconfig/cnfexpr.c | 82 ++++++++++++++++++++++++++++++++++++++++- scripts/parse_kconfig/cnfexpr.h | 5 ++- scripts/parse_kconfig/output.c | 20 ++++------ scripts/parse_kconfig/parse.c | 14 +++++-- scripts/parse_kconfig/symlist.c | 7 +++- scripts/parse_kconfig/symlist.h | 2 + 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); -- cgit v1.2.3