aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/config/expr.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2020-04-12 00:09:52 +0200
committerJo-Philipp Wich <jo@mein.io>2020-04-12 00:10:47 +0200
commit7b1d809a8d8620032553845cf4a8819a19508687 (patch)
treee9c221f4cee621bbbfa2d02ac2870b0d3caaa4a4 /scripts/config/expr.c
parent6c16d64b2a0bb063a89225dcaabd50c00bce7aa2 (diff)
downloadupstream-7b1d809a8d8620032553845cf4a8819a19508687.tar.gz
upstream-7b1d809a8d8620032553845cf4a8819a19508687.tar.bz2
upstream-7b1d809a8d8620032553845cf4a8819a19508687.zip
Revert "build: scripts/config - update to kconfig-v5.6"
This reverts commit dcf3e63a35d05e7e5103819c0f17195bfafe9baa. The kconfig update requires further testing and refinement until it can remain in tree. Main problems are: - Recursive deps are now fatal instead of a warning - Previously legal syntax now leads to hard failures - It fails all package builds since multiple days The updated kconfig implementation needs to cope with the current status quo in the various package feeds before we can reconsider it for master. It is not desirable that single broken packages can hard-fail the entire build pipeline. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'scripts/config/expr.c')
-rw-r--r--scripts/config/expr.c216
1 files changed, 61 insertions, 155 deletions
diff --git a/scripts/config/expr.c b/scripts/config/expr.c
index 81ebf8108c..8cee597d33 100644
--- a/scripts/config/expr.c
+++ b/scripts/config/expr.c
@@ -1,10 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
*/
-#include <ctype.h>
-#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -13,6 +11,7 @@
#define DEBUG_EXPR 0
+static int expr_eq(struct expr *e1, struct expr *e2);
static struct expr *expr_eliminate_yn(struct expr *e);
struct expr *expr_alloc_symbol(struct symbol *sym)
@@ -95,7 +94,7 @@ struct expr *expr_copy(const struct expr *org)
e->right.expr = expr_copy(org->right.expr);
break;
default:
- fprintf(stderr, "can't copy type %d\n", e->type);
+ printf("can't copy type %d\n", e->type);
free(e);
e = NULL;
break;
@@ -114,7 +113,7 @@ void expr_free(struct expr *e)
break;
case E_NOT:
expr_free(e->left.expr);
- break;
+ return;
case E_EQUAL:
case E_GEQ:
case E_GTH:
@@ -128,7 +127,7 @@ void expr_free(struct expr *e)
expr_free(e->right.expr);
break;
default:
- fprintf(stderr, "how to free type %d?\n", e->type);
+ printf("how to free type %d?\n", e->type);
break;
}
free(e);
@@ -139,18 +138,8 @@ static int trans_count;
#define e1 (*ep1)
#define e2 (*ep2)
-/*
- * expr_eliminate_eq() helper.
- *
- * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
- * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
- * against all other leaves. Two equal leaves are both replaced with either 'y'
- * or 'n' as appropriate for 'type', to be eliminated later.
- */
static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
{
- /* Recurse down to leaves */
-
if (e1->type == type) {
__expr_eliminate_eq(type, &e1->left.expr, &e2);
__expr_eliminate_eq(type, &e1->right.expr, &e2);
@@ -161,18 +150,12 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
__expr_eliminate_eq(type, &e1, &e2->right.expr);
return;
}
-
- /* e1 and e2 are leaves. Compare them. */
-
if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
e1->left.sym == e2->left.sym &&
(e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
return;
if (!expr_eq(e1, e2))
return;
-
- /* e1 and e2 are equal leaves. Prepare them for elimination. */
-
trans_count++;
expr_free(e1); expr_free(e2);
switch (type) {
@@ -189,35 +172,6 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
}
}
-/*
- * Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both.
- * Example reductions:
- *
- * ep1: A && B -> ep1: y
- * ep2: A && B && C -> ep2: C
- *
- * ep1: A || B -> ep1: n
- * ep2: A || B || C -> ep2: C
- *
- * ep1: A && (B && FOO) -> ep1: FOO
- * ep2: (BAR && B) && A -> ep2: BAR
- *
- * ep1: A && (B || C) -> ep1: y
- * ep2: (C || B) && A -> ep2: y
- *
- * Comparisons are done between all operands at the same "level" of && or ||.
- * For example, in the expression 'e1 && (e2 || e3) && (e4 || e5)', the
- * following operands will be compared:
- *
- * - 'e1', 'e2 || e3', and 'e4 || e5', against each other
- * - e2 against e3
- * - e4 against e5
- *
- * Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and
- * '(e1 && e2) && e3' are both a single level.
- *
- * See __expr_eliminate_eq() as well.
- */
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
{
if (!e1 || !e2)
@@ -243,23 +197,10 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
#undef e1
#undef e2
-/*
- * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two
- * &&/|| expressions are considered equal if every operand in one expression
- * equals some operand in the other (operands do not need to appear in the same
- * order), recursively.
- */
-int expr_eq(struct expr *e1, struct expr *e2)
+static int expr_eq(struct expr *e1, struct expr *e2)
{
int res, old_count;
- /*
- * A NULL expr is taken to be yes, but there's also a different way to
- * represent yes. expr_is_yes() checks for either representation.
- */
- if (!e1 || !e2)
- return expr_is_yes(e1) && expr_is_yes(e2);
-
if (e1->type != e2->type)
return 0;
switch (e1->type) {
@@ -302,17 +243,6 @@ int expr_eq(struct expr *e1, struct expr *e2)
return 0;
}
-/*
- * Recursively performs the following simplifications in-place (as well as the
- * corresponding simplifications with swapped operands):
- *
- * expr && n -> n
- * expr && y -> expr
- * expr || n -> expr
- * expr || y -> y
- *
- * Returns the optimized expression.
- */
static struct expr *expr_eliminate_yn(struct expr *e)
{
struct expr *tmp;
@@ -586,21 +516,12 @@ static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
return NULL;
}
-/*
- * expr_eliminate_dups() helper.
- *
- * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
- * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
- * against all other leaves to look for simplifications.
- */
static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
{
#define e1 (*ep1)
#define e2 (*ep2)
struct expr *tmp;
- /* Recurse down to leaves */
-
if (e1->type == type) {
expr_eliminate_dups1(type, &e1->left.expr, &e2);
expr_eliminate_dups1(type, &e1->right.expr, &e2);
@@ -611,9 +532,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
expr_eliminate_dups1(type, &e1, &e2->right.expr);
return;
}
-
- /* e1 and e2 are leaves. Compare and process them. */
-
if (e1 == e2)
return;
@@ -650,17 +568,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
#undef e2
}
-/*
- * Rewrites 'e' in-place to remove ("join") duplicate and other redundant
- * operands.
- *
- * Example simplifications:
- *
- * A || B || A -> A || B
- * A && B && A=y -> A=y && B
- *
- * Returns the deduplicated expression.
- */
struct expr *expr_eliminate_dups(struct expr *e)
{
int oldcount;
@@ -677,7 +584,6 @@ struct expr *expr_eliminate_dups(struct expr *e)
;
}
if (!trans_count)
- /* No simplifications done in this pass. We're done */
break;
e = expr_eliminate_yn(e);
}
@@ -685,12 +591,6 @@ struct expr *expr_eliminate_dups(struct expr *e)
return e;
}
-/*
- * Performs various simplifications involving logical operators and
- * comparisons.
- *
- * Allocates and returns a new expression.
- */
struct expr *expr_transform(struct expr *e)
{
struct expr *tmp;
@@ -905,20 +805,6 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
return false;
}
-/*
- * Inserts explicit comparisons of type 'type' to symbol 'sym' into the
- * expression 'e'.
- *
- * Examples transformations for type == E_UNEQUAL, sym == &symbol_no:
- *
- * A -> A!=n
- * !A -> A=n
- * A && B -> !(A=n || B=n)
- * A || B -> !(A=n && B=n)
- * A && (B || C) -> !(A=n || (B=n && C=n))
- *
- * Allocates and returns a new expression.
- */
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
{
struct expr *e1, *e2;
@@ -988,6 +874,7 @@ enum string_value_kind {
k_string,
k_signed,
k_unsigned,
+ k_invalid
};
union string_value {
@@ -1018,10 +905,13 @@ static enum string_value_kind expr_parse_string(const char *str,
val->u = strtoull(str, &tail, 16);
kind = k_unsigned;
break;
- default:
+ case S_STRING:
+ case S_UNKNOWN:
val->s = strtoll(str, &tail, 0);
kind = k_signed;
break;
+ default:
+ return k_invalid;
}
return !errno && !*tail && tail > str && isxdigit(tail[-1])
? kind : k_string;
@@ -1077,7 +967,13 @@ tristate expr_calc_value(struct expr *e)
if (k1 == k_string || k2 == k_string)
res = strcmp(str1, str2);
- else if (k1 == k_unsigned || k2 == k_unsigned)
+ else if (k1 == k_invalid || k2 == k_invalid) {
+ if (e->type != E_EQUAL && e->type != E_UNEQUAL) {
+ printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2);
+ return no;
+ }
+ res = strcmp(str1, str2);
+ } else if (k1 == k_unsigned || k2 == k_unsigned)
res = (lval.u > rval.u) - (lval.u < rval.u);
else /* if (k1 == k_signed && k2 == k_signed) */
res = (lval.s > rval.s) - (lval.s < rval.s);
@@ -1135,9 +1031,49 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
return 0;
}
-void expr_print(struct expr *e,
- void (*fn)(void *, struct symbol *, const char *),
- void *data, int prevtoken)
+static inline struct expr *
+expr_get_leftmost_symbol(const struct expr *e)
+{
+
+ if (e == NULL)
+ return NULL;
+
+ while (e->type != E_SYMBOL)
+ e = e->left.expr;
+
+ return expr_copy(e);
+}
+
+/*
+ * Given expression `e1' and `e2', returns the leaf of the longest
+ * sub-expression of `e1' not containing 'e2.
+ */
+struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
+{
+ struct expr *ret;
+
+ switch (e1->type) {
+ case E_OR:
+ return expr_alloc_and(
+ expr_simplify_unmet_dep(e1->left.expr, e2),
+ expr_simplify_unmet_dep(e1->right.expr, e2));
+ case E_AND: {
+ struct expr *e;
+ e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
+ e = expr_eliminate_dups(e);
+ ret = (!expr_eq(e, e1)) ? e1 : NULL;
+ expr_free(e);
+ break;
+ }
+ default:
+ ret = e1;
+ break;
+ }
+
+ return expr_get_leftmost_symbol(ret);
+}
+
+void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
{
if (!e) {
fn(data, NULL, "y");
@@ -1271,33 +1207,3 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
{
expr_print(e, expr_print_gstr_helper, gs, E_NONE);
}
-
-/*
- * Transform the top level "||" tokens into newlines and prepend each
- * line with a minus. This makes expressions much easier to read.
- * Suitable for reverse dependency expressions.
- */
-static void expr_print_revdep(struct expr *e,
- void (*fn)(void *, struct symbol *, const char *),
- void *data, tristate pr_type, const char **title)
-{
- if (e->type == E_OR) {
- expr_print_revdep(e->left.expr, fn, data, pr_type, title);
- expr_print_revdep(e->right.expr, fn, data, pr_type, title);
- } else if (expr_calc_value(e) == pr_type) {
- if (*title) {
- fn(data, NULL, *title);
- *title = NULL;
- }
-
- fn(data, NULL, " - ");
- expr_print(e, fn, data, E_NONE);
- fn(data, NULL, "\n");
- }
-}
-
-void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
- tristate pr_type, const char *title)
-{
- expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
-}