-rw-r--r-- | scripts/kconfig/expr.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index d1af2a5..3f15ae8 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -42,32 +42,39 @@ struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symb { struct expr *e = malloc(sizeof(*e)); memset(e, 0, sizeof(*e)); e->type = type; e->left.sym = s1; e->right.sym = s2; return e; } struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) { if (!e1) return e2; return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; } +struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) +{ + if (!e1) + return e2; + return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; +} + struct expr *expr_copy(struct expr *org) { struct expr *e; if (!org) return NULL; e = malloc(sizeof(*org)); memcpy(e, org, sizeof(*org)); switch (org->type) { case E_SYMBOL: e->left = org->left; break; case E_NOT: e->left.expr = expr_copy(org->left.expr); break; @@ -145,35 +152,48 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e switch (type) { case E_OR: e1 = expr_alloc_symbol(&symbol_no); e2 = expr_alloc_symbol(&symbol_no); break; case E_AND: e1 = expr_alloc_symbol(&symbol_yes); e2 = expr_alloc_symbol(&symbol_yes); break; default: ; } } void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) { - if (!e1 || !e2 || e1->type != e2->type) + if (!e1 || !e2) return; + switch (e1->type) { + case E_OR: + case E_AND: __expr_eliminate_eq(e1->type, ep1, ep2); + default: + ; + } + if (e1->type != e2->type) switch (e2->type) { + case E_OR: + case E_AND: + __expr_eliminate_eq(e2->type, ep1, ep2); + default: + ; + } e1 = expr_eliminate_yn(e1); e2 = expr_eliminate_yn(e2); } #undef e1 #undef e2 int expr_eq(struct expr *e1, struct expr *e2) { int res, old_count; if (e1->type != e2->type) return 0; switch (e1->type) { case E_EQUAL: case E_UNEQUAL: @@ -182,32 +202,33 @@ int expr_eq(struct expr *e1, struct expr *e2) return e1->left.sym == e2->left.sym; case E_NOT: return expr_eq(e1->left.expr, e2->left.expr); case E_AND: case E_OR: e1 = expr_copy(e1); e2 = expr_copy(e2); old_count = trans_count; expr_eliminate_eq(&e1, &e2); res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && e1->left.sym == e2->left.sym); expr_free(e1); expr_free(e2); trans_count = old_count; return res; case E_CHOICE: + case E_RANGE: case E_NONE: /* panic */; } print_expr(0, e1, 0); printf(" = "); print_expr(0, e2, 0); printf(" ?\n"); return 0; } struct expr *expr_eliminate_yn(struct expr *e) { struct expr *tmp; @@ -884,50 +905,51 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb if (sym == &symbol_mod) return expr_alloc_symbol(&symbol_no); if (sym == &symbol_no) return expr_alloc_one(E_NOT, expr_copy(e)); } else { if (sym == &symbol_yes) return expr_alloc_one(E_NOT, expr_copy(e)); if (sym == &symbol_mod) return expr_alloc_symbol(&symbol_yes); if (sym == &symbol_no) return expr_copy(e); } break; case E_SYMBOL: return expr_alloc_comp(type, e->left.sym, sym); case E_CHOICE: + case E_RANGE: case E_NONE: /* panic */; } return NULL; } tristate expr_calc_value(struct expr *e) { tristate val1, val2; const char *str1, *str2; if (!e) return yes; switch (e->type) { case E_SYMBOL: sym_calc_value(e->left.sym); - return S_TRI(e->left.sym->curr); + return e->left.sym->curr.tri; case E_AND: val1 = expr_calc_value(e->left.expr); val2 = expr_calc_value(e->right.expr); return E_AND(val1, val2); case E_OR: val1 = expr_calc_value(e->left.expr); val2 = expr_calc_value(e->right.expr); return E_OR(val1, val2); case E_NOT: val1 = expr_calc_value(e->left.expr); return E_NOT(val1); case E_EQUAL: sym_calc_value(e->left.sym); sym_calc_value(e->right.sym); str1 = sym_get_string_value(e->left.sym); str2 = sym_get_string_value(e->right.sym); @@ -1004,37 +1026,44 @@ void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, in case E_UNEQUAL: fn(data, e->left.sym->name); fn(data, "!="); fn(data, e->right.sym->name); break; case E_OR: expr_print(e->left.expr, fn, data, E_OR); fn(data, " || "); expr_print(e->right.expr, fn, data, E_OR); break; case E_AND: expr_print(e->left.expr, fn, data, E_AND); fn(data, " && "); expr_print(e->right.expr, fn, data, E_AND); break; case E_CHOICE: + fn(data, e->right.sym->name); if (e->left.expr) { - expr_print(e->left.expr, fn, data, E_CHOICE); fn(data, " ^ "); + expr_print(e->left.expr, fn, data, E_CHOICE); } + break; + case E_RANGE: + fn(data, "["); + fn(data, e->left.sym->name); + fn(data, " "); fn(data, e->right.sym->name); + fn(data, "]"); break; default: { char buf[32]; sprintf(buf, "<unknown type %d>", e->type); fn(data, buf); break; } } if (expr_compare_type(prevtoken, e->type) > 0) fn(data, ")"); } static void expr_print_file_helper(void *data, const char *str) { fwrite(str, strlen(str), 1, data); |