aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/config/symbol.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/symbol.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/symbol.c')
-rw-r--r--scripts/config/symbol.c269
1 files changed, 182 insertions, 87 deletions
diff --git a/scripts/config/symbol.c b/scripts/config/symbol.c
index b1dd9be29d..31f268a4ee 100644
--- a/scripts/config/symbol.c
+++ b/scripts/config/symbol.c
@@ -1,6 +1,6 @@
-// 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>
@@ -33,6 +33,33 @@ struct symbol *sym_defconfig_list;
struct symbol *modules_sym;
tristate modules_val;
+struct expr *sym_env_list;
+
+static void sym_add_default(struct symbol *sym, const char *def)
+{
+ struct property *prop = prop_alloc(P_DEFAULT, sym);
+
+ prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
+}
+
+void sym_init(void)
+{
+ struct symbol *sym;
+ struct utsname uts;
+ static bool inited = false;
+
+ if (inited)
+ return;
+ inited = true;
+
+ uname(&uts);
+
+ sym = sym_lookup("UNAME_RELEASE", 0);
+ sym->type = S_STRING;
+ sym->flags |= SYMBOL_AUTO;
+ sym_add_default(sym, uts.release);
+}
+
enum symbol_type sym_get_type(struct symbol *sym)
{
enum symbol_type type = sym->type;
@@ -50,7 +77,7 @@ const char *sym_type_name(enum symbol_type type)
{
switch (type) {
case S_BOOLEAN:
- return "bool";
+ return "boolean";
case S_TRISTATE:
return "tristate";
case S_INT:
@@ -61,6 +88,8 @@ const char *sym_type_name(enum symbol_type type)
return "string";
case S_UNKNOWN:
return "unknown";
+ case S_OTHER:
+ break;
}
return "???";
}
@@ -74,6 +103,15 @@ struct property *sym_get_choice_prop(struct symbol *sym)
return NULL;
}
+struct property *sym_get_env_prop(struct symbol *sym)
+{
+ struct property *prop;
+
+ for_all_properties(sym, prop, P_ENV)
+ return prop;
+ return NULL;
+}
+
static struct property *sym_get_default_prop(struct symbol *sym)
{
struct property *prop;
@@ -86,7 +124,7 @@ static struct property *sym_get_default_prop(struct symbol *sym)
return NULL;
}
-struct property *sym_get_range_prop(struct symbol *sym)
+static struct property *sym_get_range_prop(struct symbol *sym)
{
struct property *prop;
@@ -145,7 +183,7 @@ static void sym_validate_range(struct symbol *sym)
sprintf(str, "%lld", val2);
else
sprintf(str, "0x%llx", val2);
- sym->curr.val = xstrdup(str);
+ sym->curr.val = strdup(str);
}
static void sym_set_changed(struct symbol *sym)
@@ -205,7 +243,7 @@ static void sym_calc_visibility(struct symbol *sym)
tri = yes;
if (sym->dir_dep.expr)
tri = expr_calc_value(sym->dir_dep.expr);
- if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
+ if (tri == mod)
tri = yes;
if (sym->dir_dep.tri != tri) {
sym->dir_dep.tri = tri;
@@ -220,15 +258,6 @@ static void sym_calc_visibility(struct symbol *sym)
sym->rev_dep.tri = tri;
sym_set_changed(sym);
}
- tri = no;
- if (sym->implied.expr && sym->dir_dep.tri != no)
- tri = expr_calc_value(sym->implied.expr);
- if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
- tri = yes;
- if (sym->implied.tri != tri) {
- sym->implied.tri = tri;
- sym_set_changed(sym);
- }
}
/*
@@ -333,13 +362,11 @@ void sym_calc_value(struct symbol *sym)
sym->curr.tri = no;
return;
}
- sym->flags &= ~SYMBOL_WRITE;
+ if (!sym_is_choice_value(sym))
+ sym->flags &= ~SYMBOL_WRITE;
sym_calc_visibility(sym);
- if (sym->visible != no)
- sym->flags |= SYMBOL_WRITE;
-
/* set default if recursively called */
sym->curr = newval;
@@ -354,6 +381,7 @@ void sym_calc_value(struct symbol *sym)
/* if the symbol is visible use the user value
* if available, otherwise try the default value
*/
+ sym->flags |= SYMBOL_WRITE;
if (sym_has_value(sym)) {
newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
sym->visible);
@@ -369,28 +397,26 @@ void sym_calc_value(struct symbol *sym)
newval.tri = EXPR_AND(expr_calc_value(prop->expr),
prop->visible.tri);
}
- if (sym->implied.tri != no) {
- sym->flags |= SYMBOL_WRITE;
- newval.tri = EXPR_OR(newval.tri, sym->implied.tri);
- }
}
calc_newval:
- if (sym->dir_dep.tri < sym->rev_dep.tri) {
+ if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
newval.tri = no;
} else {
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
}
}
- if (newval.tri == mod &&
- (sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes))
+ if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
newval.tri = yes;
break;
case S_STRING:
case S_HEX:
case S_INT:
- if (sym->visible != no && sym_has_value(sym)) {
- newval.val = sym->def[S_DEF_USER].val;
- break;
+ if (sym->visible != no) {
+ sym->flags |= SYMBOL_WRITE;
+ if (sym_has_value(sym)) {
+ newval.val = sym->def[S_DEF_USER].val;
+ break;
+ }
}
prop = sym_get_default_prop(sym);
if (prop) {
@@ -432,7 +458,7 @@ void sym_calc_value(struct symbol *sym)
}
}
- if (sym->flags & SYMBOL_NO_WRITE)
+ if (sym->flags & SYMBOL_AUTO)
sym->flags &= ~SYMBOL_WRITE;
if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
@@ -464,8 +490,6 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val)
return false;
if (sym->visible <= sym->rev_dep.tri)
return false;
- if (sym->implied.tri == yes && val == mod)
- return false;
if (sym_is_choice_value(sym) && sym->visible == yes)
return val == yes;
return val >= sym->rev_dep.tri && val <= sym->visible;
@@ -718,10 +742,6 @@ const char *sym_get_string_default(struct symbol *sym)
if (sym->type == S_BOOLEAN && val == mod)
val = yes;
- /* adjust the default value if this symbol is implied by another */
- if (val < sym->implied.tri)
- val = sym->implied.tri;
-
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
@@ -735,6 +755,7 @@ const char *sym_get_string_default(struct symbol *sym)
return str;
case S_STRING:
return str;
+ case S_OTHER:
case S_UNKNOWN:
break;
}
@@ -765,7 +786,7 @@ const char *sym_get_string_value(struct symbol *sym)
return (const char *)sym->curr.val;
}
-bool sym_is_changeable(struct symbol *sym)
+bool sym_is_changable(struct symbol *sym)
{
return sym->visible > sym->rev_dep.tri;
}
@@ -802,7 +823,7 @@ struct symbol *sym_lookup(const char *name, int flags)
: !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
return symbol;
}
- new_name = xstrdup(name);
+ new_name = strdup(name);
} else {
new_name = NULL;
hash = 0;
@@ -847,6 +868,55 @@ struct symbol *sym_find(const char *name)
return symbol;
}
+/*
+ * Expand symbol's names embedded in the string given in argument. Symbols'
+ * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
+ * the empty string.
+ */
+const char *sym_expand_string_value(const char *in)
+{
+ const char *src;
+ char *res;
+ size_t reslen;
+
+ reslen = strlen(in) + 1;
+ res = xmalloc(reslen);
+ res[0] = '\0';
+
+ while ((src = strchr(in, '$'))) {
+ char *p, name[SYMBOL_MAXLENGTH];
+ const char *symval = "";
+ struct symbol *sym;
+ size_t newlen;
+
+ strncat(res, in, src - in);
+ src++;
+
+ p = name;
+ while (isalnum(*src) || *src == '_')
+ *p++ = *src++;
+ *p = '\0';
+
+ sym = sym_find(name);
+ if (sym != NULL) {
+ sym_calc_value(sym);
+ symval = sym_get_string_value(sym);
+ }
+
+ newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
+ if (newlen > reslen) {
+ reslen = newlen;
+ res = realloc(res, reslen);
+ }
+
+ strcat(res, symval);
+ in = src;
+ }
+ strcat(res, in);
+
+ return res;
+}
+
const char *sym_escape_string_value(const char *in)
{
const char *p;
@@ -963,7 +1033,7 @@ struct symbol **sym_re_search(const char *pattern)
}
if (sym_match_arr) {
qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp);
- sym_arr = malloc((cnt+1) * sizeof(struct symbol *));
+ sym_arr = malloc((cnt+1) * sizeof(struct symbol));
if (!sym_arr)
goto sym_re_search_free;
for (i = 0; i < cnt; i++)
@@ -988,7 +1058,7 @@ static struct dep_stack {
struct dep_stack *prev, *next;
struct symbol *sym;
struct property *prop;
- struct expr **expr;
+ struct expr *expr;
} *check_top;
static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
@@ -1052,52 +1122,37 @@ static void sym_check_print_recursive(struct symbol *last_sym)
if (stack->sym == last_sym)
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
prop->file->name, prop->lineno);
-
- if (sym_is_choice(sym)) {
- fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
- menu->file->name, menu->lineno,
- sym->name ? sym->name : "<choice>",
- next_sym->name ? next_sym->name : "<choice>");
- } else if (sym_is_choice_value(sym)) {
- fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
- menu->file->name, menu->lineno,
- sym->name ? sym->name : "<choice>",
- next_sym->name ? next_sym->name : "<choice>");
- } else if (stack->expr == &sym->dir_dep.expr) {
- fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
+ fprintf(stderr, "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n");
+ fprintf(stderr, "subsection \"Kconfig recursive dependency limitations\"\n");
+ if (stack->expr) {
+ fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
prop->file->name, prop->lineno,
sym->name ? sym->name : "<choice>",
+ prop_get_type_name(prop->type),
next_sym->name ? next_sym->name : "<choice>");
- } else if (stack->expr == &sym->rev_dep.expr) {
- fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
+ } else if (stack->prop) {
+ fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
prop->file->name, prop->lineno,
sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>");
- } else if (stack->expr == &sym->implied.expr) {
- fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n",
- prop->file->name, prop->lineno,
+ } else if (sym_is_choice(sym)) {
+ fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
+ menu->file->name, menu->lineno,
sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>");
- } else if (stack->expr) {
- fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
- prop->file->name, prop->lineno,
+ } else if (sym_is_choice_value(sym)) {
+ fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
+ menu->file->name, menu->lineno,
sym->name ? sym->name : "<choice>",
- prop_get_type_name(prop->type),
next_sym->name ? next_sym->name : "<choice>");
} else {
- fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n",
+ fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
prop->file->name, prop->lineno,
sym->name ? sym->name : "<choice>",
- prop_get_type_name(prop->type),
next_sym->name ? next_sym->name : "<choice>");
}
}
- fprintf(stderr,
- "For a resolution refer to Documentation/kbuild/kconfig-language.rst\n"
- "subsection \"Kconfig recursive dependency limitations\"\n"
- "\n");
-
if (check_top == &cv_stack)
dep_stack_remove();
}
@@ -1132,7 +1187,7 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
default:
break;
}
- fprintf(stderr, "Oops! How to check %d?\n", e->type);
+ printf("Oops! How to check %d?\n", e->type);
return NULL;
}
@@ -1145,26 +1200,12 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
dep_stack_insert(&stack, sym);
- stack.expr = &sym->dir_dep.expr;
- sym2 = sym_check_expr_deps(sym->dir_dep.expr);
- if (sym2)
- goto out;
-
- stack.expr = &sym->rev_dep.expr;
sym2 = sym_check_expr_deps(sym->rev_dep.expr);
if (sym2)
goto out;
- stack.expr = &sym->implied.expr;
- sym2 = sym_check_expr_deps(sym->implied.expr);
- if (sym2)
- goto out;
-
- stack.expr = NULL;
-
for (prop = sym->prop; prop; prop = prop->next) {
- if (prop->type == P_CHOICE || prop->type == P_SELECT ||
- prop->type == P_IMPLY)
+ if (prop->type == P_CHOICE || prop->type == P_SELECT)
continue;
stack.prop = prop;
sym2 = sym_check_expr_deps(prop->visible.expr);
@@ -1172,7 +1213,7 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
break;
if (prop->type != P_DEFAULT || sym_is_choice(sym))
continue;
- stack.expr = &prop->expr;
+ stack.expr = prop->expr;
sym2 = sym_check_expr_deps(prop->expr);
if (sym2)
break;
@@ -1250,9 +1291,34 @@ struct symbol *sym_check_deps(struct symbol *sym)
sym->flags &= ~SYMBOL_CHECK;
}
+ if (sym2 && sym2 == sym)
+ sym2 = NULL;
+
return sym2;
}
+struct property *prop_alloc(enum prop_type type, struct symbol *sym)
+{
+ struct property *prop;
+ struct property **propp;
+
+ prop = xmalloc(sizeof(*prop));
+ memset(prop, 0, sizeof(*prop));
+ prop->type = type;
+ prop->sym = sym;
+ prop->file = current_file;
+ prop->lineno = zconf_lineno();
+
+ /* append property to the prop list of symbol */
+ if (sym) {
+ for (propp = &sym->prop; *propp; propp = &(*propp)->next)
+ ;
+ *propp = prop;
+ }
+
+ return prop;
+}
+
struct symbol *prop_get_symbol(struct property *prop)
{
if (prop->expr && (prop->expr->type == E_SYMBOL ||
@@ -1266,6 +1332,8 @@ const char *prop_get_type_name(enum prop_type type)
switch (type) {
case P_PROMPT:
return "prompt";
+ case P_ENV:
+ return "env";
case P_COMMENT:
return "comment";
case P_MENU:
@@ -1276,8 +1344,6 @@ const char *prop_get_type_name(enum prop_type type)
return "choice";
case P_SELECT:
return "select";
- case P_IMPLY:
- return "imply";
case P_RANGE:
return "range";
case P_SYMBOL:
@@ -1289,3 +1355,32 @@ const char *prop_get_type_name(enum prop_type type)
}
return "unknown";
}
+
+static void prop_add_env(const char *env)
+{
+ struct symbol *sym, *sym2;
+ struct property *prop;
+ char *p;
+
+ sym = current_entry->sym;
+ sym->flags |= SYMBOL_AUTO;
+ for_all_properties(sym, prop, P_ENV) {
+ sym2 = prop_get_symbol(prop);
+ if (strcmp(sym2->name, env))
+ menu_warn(current_entry, "redefining environment symbol from %s",
+ sym2->name);
+ return;
+ }
+
+ prop = prop_alloc(P_ENV, sym);
+ prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
+
+ sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
+ sym_env_list->right.sym = sym;
+
+ p = getenv(env);
+ if (p)
+ sym_add_default(sym, p);
+ else
+ menu_warn(current_entry, "environment variable %s undefined", env);
+}