]> rtime.felk.cvut.cz Git - linux-conf-perf.git/commitdiff
Fix parse_kconfig choice parsing
authorKarel Kočí <cynerd@email.cz>
Sat, 12 Sep 2015 09:46:26 +0000 (11:46 +0200)
committerKarel Kočí <cynerd@email.cz>
Sat, 12 Sep 2015 09:46:26 +0000 (11:46 +0200)
Parsing choices was implemented wrong. For non-optional choice output
rules must contain also dependency of all choice symbols. Because if no
choice symbol has fulfilled dependencies, than choice shouldn't be
selected.

scripts/parse_kconfig/boolexpr.c
scripts/parse_kconfig/boolexpr.h
scripts/parse_kconfig/parse.c

index 4d5865482309d1116a1fdeb4c69b762b94609cb7..b6f008dd6fd6583a06494c4bdc3453a13771c142 100644 (file)
@@ -4,7 +4,7 @@ struct boolexpr *boolexpr_eql(struct symlist *sl, struct symbol *sym1,
                               struct symbol *sym2);
 
 struct boolexpr *boolexpr_kconfig(struct symlist *sl, struct expr *expr,
-                                  bool modulesym) {
+                                  bool modulesym, struct symbol **as_true) {
     struct stck {
         struct expr *expr;
         struct boolexpr *bl;
@@ -30,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, modulesym);
+            rtn = boolexpr_sym(sl, expr->left.sym, modulesym, as_true);
             goto go_up;
         case E_NOT:
             if (rtn == NULL)
@@ -111,7 +111,7 @@ struct boolexpr *boolexpr_false() {
 }
 
 struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym,
-                              bool modulesym) {
+                              bool modulesym, struct symbol **as_true) {
     struct boolexpr *rtn;
     rtn = malloc(sizeof(struct boolexpr));
     rtn->overusage = 0;
@@ -125,6 +125,14 @@ struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym,
     } else if (!strcmp(sym->name, "y")) {
         rtn->type = BT_TRUE;
     } else {
+        if (as_true != NULL) {
+            for (; *as_true != NULL; as_true++) {
+                if (!strcmp((*as_true)->name, sym->name)) {
+                    rtn->type = BT_TRUE;
+                    return rtn;
+                }
+            }
+        }
         rtn->id = symlist_id(sl, sym->name);
         if (rtn->id != 0)
             rtn->type = BT_SYM;
@@ -144,18 +152,18 @@ struct boolexpr *boolexpr_eql(struct symlist *sl,
         return rtn;
     }
     if (!strcmp(sym2->name, "n"))
-        return boolexpr_not(boolexpr_sym(sl, sym1, false));
+        return boolexpr_not(boolexpr_sym(sl, sym1, false, NULL));
     if (!strcmp(sym2->name, "y"))
-        return boolexpr_sym(sl, sym1, false);
+        return boolexpr_sym(sl, sym1, false, NULL);
     // sym1 <-> sym2
     // (!sym1 || sym2) && (sym1 || !sym2)
     return
         boolexpr_and(boolexpr_or
-                     (boolexpr_not(boolexpr_sym(sl, sym1, false)),
-                      boolexpr_sym(sl, sym2, false)),
-                     boolexpr_or(boolexpr_sym(sl, sym1, false),
+                     (boolexpr_not(boolexpr_sym(sl, sym1, false, NULL)),
+                      boolexpr_sym(sl, sym2, false, NULL)),
+                     boolexpr_or(boolexpr_sym(sl, sym1, false, NULL),
                                  boolexpr_not(boolexpr_sym
-                                              (sl, sym2, false))));
+                                              (sl, sym2, false, NULL))));
 }
 
 struct boolexpr *boolexpr_or(struct boolexpr *e1, struct boolexpr *e2) {
index 5a368bf7ac563f976a2c4823ba73ac5aa49dadf9..5eeb3f8fc6bab3594111e33fd97815f7f37cff00 100644 (file)
@@ -21,12 +21,12 @@ struct boolexpr {
 };
 
 struct boolexpr *boolexpr_kconfig(struct symlist *sl, struct expr *expr,
-                                  bool modulesym);
+                                  bool modulesym, struct symbol **as_true);
 
 struct boolexpr *boolexpr_true();
 struct boolexpr *boolexpr_false();
 struct boolexpr *boolexpr_sym(struct symlist *sl, struct symbol *sym,
-                              bool modulesym);
+                              bool modulesym, struct symbol **as_true);
 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);
index 9b6c1cb5622eedf544fff3ab3b94284b98fc402f..9de456fe94d384079eee11e0750486620ca5e6c5 100644 (file)
@@ -99,7 +99,7 @@ void cpy_dep() {
         if (sym->type == S_BOOLEAN || sym->type == S_TRISTATE) {
             el_id = symlist_id(gsymlist, sym->name);
             el = &(gsymlist->array[el_id - 1]);
-            boolsym = boolexpr_sym(gsymlist, sym, false);
+            boolsym = boolexpr_sym(gsymlist, sym, false, NULL);
             Iprintf("Processing: %s\n", sym->name);
             // Visibility
             for_all_prompts(sym, prop) {
@@ -108,7 +108,7 @@ void cpy_dep() {
                     doutput_expr(prop->visible.expr);
                     struct boolexpr *vis =
                         boolexpr_kconfig(gsymlist, prop->visible.expr,
-                                         false);
+                                         false, NULL);
                     if (el->vis == NULL) {
                         el->vis = vis;
                     } else {
@@ -130,13 +130,13 @@ void cpy_dep() {
                 Dprintf(" Default value:\n");
                 doutput_expr(prop->expr);
                 struct boolexpr *def =
-                    boolexpr_kconfig(gsymlist, prop->expr, true);
+                    boolexpr_kconfig(gsymlist, prop->expr, true, NULL);
                 if (prop->visible.expr != NULL)
                     def =
                         boolexpr_and(def,
                                      boolexpr_kconfig(gsymlist,
                                                       prop->visible.expr,
-                                                      false));
+                                                      false, NULL));
                 if (el->def == NULL) {
                     el->def = def;
                 } else {
@@ -150,7 +150,7 @@ void cpy_dep() {
                 Dprintf(" Dependency:\n");
                 doutput_expr(sym->dir_dep.expr);
                 el->dep =
-                    boolexpr_kconfig(gsymlist, sym->dir_dep.expr, false);
+                    boolexpr_kconfig(gsymlist, sym->dir_dep.expr, false, NULL);
             } else
                 el->dep = boolexpr_true();
             // Reverse dependency expression
@@ -158,7 +158,7 @@ void cpy_dep() {
                 Dprintf(" Reverse dependency:\n");
                 doutput_expr(sym->rev_dep.expr);
                 el->rev_dep =
-                    boolexpr_kconfig(gsymlist, sym->rev_dep.expr, false);
+                    boolexpr_kconfig(gsymlist, sym->rev_dep.expr, false, NULL);
             } else
                 el->rev_dep = boolexpr_false();
 
@@ -230,7 +230,7 @@ void cpy_dep() {
                 Dprintf(" Dependency:\n");
                 doutput_expr(sym->rev_dep.expr);
                 el->rev_dep =
-                    boolexpr_kconfig(gsymlist, sym->rev_dep.expr, true);
+                    boolexpr_kconfig(gsymlist, sym->rev_dep.expr, true, NULL);
             } else
                 el->rev_dep = boolexpr_true();
             for_all_choices(sym, prop) {
@@ -265,8 +265,8 @@ void cpy_dep() {
             if (el->vis->type != BT_FALSE && el->vis->type != BT_TRUE)
                 cnf_boolexpr(gsymlist, el->vis);
             // (!sym || rev_dep) && (!sym || !rev_dep || vis)
-            // For nonoptional add:
-            // (sym || !rev_dep || !vis)
+            // For nonoptional per list symbol add:
+            // (sym || !rev_dep || !vis || !dir_dep_of_list))
             if (el->rev_dep->type != BT_TRUE) {
                 output_rules_symbol(-1 * boolsym->id);
                 if (el->rev_dep->type != BT_FALSE) {
@@ -285,16 +285,36 @@ void cpy_dep() {
                 output_rules_endterm();
             }
             if (!sym_is_optional(sym)) {
-                if (el->rev_dep->type != BT_FALSE
-                    && el->vis->type != BT_FALSE) {
-                    output_rules_symbol(boolsym->id);
-                    if (el->rev_dep->type != BT_TRUE) {
-                        output_rules_symbol(-1 * el->rev_dep->id);
+                for_all_choices(sym, prop) {
+                    struct symbol *symw;
+                    struct expr *exprw;
+                    expr_list_for_each_sym(prop->expr, exprw, symw) {
+                        struct boolexpr *wdep;
+                        if (symw->dir_dep.expr != NULL) {
+                            struct symbol *settrue[] = {sym, NULL};
+                            wdep =
+                                boolexpr_kconfig(gsymlist, symw->dir_dep.expr,
+                                        false, settrue);
+                        } else
+                            wdep = boolexpr_true();
+                        cnf_boolexpr(gsymlist, wdep);
+                        if (el->rev_dep->type != BT_FALSE
+                            && el->vis->type != BT_FALSE
+                            && wdep->type != BT_FALSE) {
+                            output_rules_symbol(boolsym->id);
+                            if (el->rev_dep->type != BT_TRUE) {
+                                output_rules_symbol(-1 * el->rev_dep->id);
+                            }
+                            if (el->vis->type != BT_TRUE) {
+                                output_rules_symbol(-1 * el->vis->id);
+                            }
+                            if (wdep->type != BT_TRUE
+                                && wdep->id != boolsym->id) {
+                                output_rules_symbol(-1 * wdep->id);
+                            }
+                            output_rules_endterm();
+                        }
                     }
-                    if (el->vis->type != BT_TRUE) {
-                        output_rules_symbol(-1 * el->vis->id);
-                    }
-                    output_rules_endterm();
                 }
             }
         }