]> rtime.felk.cvut.cz Git - linux-conf-perf.git/commitdiff
parse_kconfig adding proper visibility dependency
authorKarel Kočí <cynerd@email.cz>
Mon, 4 May 2015 18:19:57 +0000 (20:19 +0200)
committerKarel Kočí <cynerd@email.cz>
Mon, 4 May 2015 18:19:57 +0000 (20:19 +0200)
For unknown reasons, output rules with generated default solution are not satisfiable.

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

index 4ce41542c6bd1e565393b13a2865d57d514f4955..4d5865482309d1116a1fdeb4c69b762b94609cb7 100644 (file)
@@ -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) {
index 52cd4a69c5b084e6ab934039c4a8edd252d2818c..5a368bf7ac563f976a2c4823ba73ac5aa49dadf9 100644 (file)
@@ -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);
index 54941dc54d8ee166254dbc260651da497574a9f5..b7ab951e782e4b25094c98c10bb195160547dc46 100644 (file)
@@ -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);
index d38dde104583f6dddb13e0f954b10e33810ee258..f81facfb3bd8e8920a883db4e7bcfefd31a24a34 100644 (file)
@@ -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);
index 234f7763099302efa08d5f6ff799cb2962bb6950..5499bffa99379d9e82f32a4453fc8532a681d262 100644 (file)
 
 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 {