Update carl9170 to latest upstream
[linux-libre-firmware.git] / carl9170fw / config / symbol.c
index 3c8bd9bb4267a874cd1fa112d4a21b569bd56296..1f9266dadedf63f2c01fb102e3e173d3349520e7 100644 (file)
@@ -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,33 +33,6 @@ 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;
@@ -77,7 +50,7 @@ const char *sym_type_name(enum symbol_type type)
 {
        switch (type) {
        case S_BOOLEAN:
-               return "boolean";
+               return "bool";
        case S_TRISTATE:
                return "tristate";
        case S_INT:
@@ -88,8 +61,6 @@ const char *sym_type_name(enum symbol_type type)
                return "string";
        case S_UNKNOWN:
                return "unknown";
-       case S_OTHER:
-               break;
        }
        return "???";
 }
@@ -103,15 +74,6 @@ 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;
@@ -124,7 +86,7 @@ static struct property *sym_get_default_prop(struct symbol *sym)
        return NULL;
 }
 
-static struct property *sym_get_range_prop(struct symbol *sym)
+struct property *sym_get_range_prop(struct symbol *sym)
 {
        struct property *prop;
 
@@ -183,7 +145,7 @@ static void sym_validate_range(struct symbol *sym)
                sprintf(str, "%lld", val2);
        else
                sprintf(str, "0x%llx", val2);
-       sym->curr.val = strdup(str);
+       sym->curr.val = xstrdup(str);
 }
 
 static void sym_set_changed(struct symbol *sym)
@@ -243,7 +205,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)
+       if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
                tri = yes;
        if (sym->dir_dep.tri != tri) {
                sym->dir_dep.tri = tri;
@@ -333,6 +295,27 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
        return def_sym;
 }
 
+static void sym_warn_unmet_dep(struct symbol *sym)
+{
+       struct gstr gs = str_new();
+
+       str_printf(&gs,
+                  "\nWARNING: unmet direct dependencies detected for %s\n",
+                  sym->name);
+       str_printf(&gs,
+                  "  Depends on [%c]: ",
+                  sym->dir_dep.tri == mod ? 'm' : 'n');
+       expr_gstr_print(sym->dir_dep.expr, &gs);
+       str_printf(&gs, "\n");
+
+       expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes,
+                              "  Selected by [y]:\n");
+       expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod,
+                              "  Selected by [m]:\n");
+
+       fputs(str_get(&gs), stderr);
+}
+
 void sym_calc_value(struct symbol *sym)
 {
        struct symbol_value newval, oldval;
@@ -371,11 +354,13 @@ void sym_calc_value(struct symbol *sym)
                sym->curr.tri = no;
                return;
        }
-       if (!sym_is_choice_value(sym))
-               sym->flags &= ~SYMBOL_WRITE;
+       sym->flags &= ~SYMBOL_WRITE;
 
        sym_calc_visibility(sym);
 
+       if (sym->visible != no)
+               sym->flags |= SYMBOL_WRITE;
+
        /* set default if recursively called */
        sym->curr = newval;
 
@@ -390,7 +375,6 @@ 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);
@@ -402,9 +386,10 @@ void sym_calc_value(struct symbol *sym)
                        if (!sym_is_choice(sym)) {
                                prop = sym_get_default_prop(sym);
                                if (prop) {
-                                       sym->flags |= SYMBOL_WRITE;
                                        newval.tri = EXPR_AND(expr_calc_value(prop->expr),
                                                              prop->visible.tri);
+                                       if (newval.tri != no)
+                                               sym->flags |= SYMBOL_WRITE;
                                }
                                if (sym->implied.tri != no) {
                                        sym->flags |= SYMBOL_WRITE;
@@ -412,18 +397,8 @@ void sym_calc_value(struct symbol *sym)
                                }
                        }
                calc_newval:
-                       if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
-                               struct expr *e;
-                               e = expr_simplify_unmet_dep(sym->rev_dep.expr,
-                                   sym->dir_dep.expr);
-                               fprintf(stderr, "warning: (");
-                               expr_fprint(e, stderr);
-                               fprintf(stderr, ") selects %s which has unmet direct dependencies (",
-                                       sym->name);
-                               expr_fprint(sym->dir_dep.expr, stderr);
-                               fprintf(stderr, ")\n");
-                               expr_free(e);
-                       }
+                       if (sym->dir_dep.tri < sym->rev_dep.tri)
+                               sym_warn_unmet_dep(sym);
                        newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
                }
                if (newval.tri == mod &&
@@ -433,12 +408,9 @@ void sym_calc_value(struct symbol *sym)
        case S_STRING:
        case S_HEX:
        case S_INT:
-               if (sym->visible != no) {
-                       sym->flags |= SYMBOL_WRITE;
-                       if (sym_has_value(sym)) {
-                               newval.val = sym->def[S_DEF_USER].val;
-                               break;
-                       }
+               if (sym->visible != no && sym_has_value(sym)) {
+                       newval.val = sym->def[S_DEF_USER].val;
+                       break;
                }
                prop = sym_get_default_prop(sym);
                if (prop) {
@@ -480,7 +452,7 @@ void sym_calc_value(struct symbol *sym)
                }
        }
 
-       if (sym->flags & SYMBOL_AUTO)
+       if (sym->flags & SYMBOL_NO_WRITE)
                sym->flags &= ~SYMBOL_WRITE;
 
        if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
@@ -783,7 +755,6 @@ const char *sym_get_string_default(struct symbol *sym)
                return str;
        case S_STRING:
                return str;
-       case S_OTHER:
        case S_UNKNOWN:
                break;
        }
@@ -851,7 +822,7 @@ struct symbol *sym_lookup(const char *name, int flags)
                                   : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
                                return symbol;
                }
-               new_name = strdup(name);
+               new_name = xstrdup(name);
        } else {
                new_name = NULL;
                hash = 0;
@@ -896,55 +867,6 @@ 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;
@@ -1086,7 +1008,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)
@@ -1150,37 +1072,52 @@ 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);
-                       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,
+
+               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>",
-                               prop_get_type_name(prop->type),
                                next_sym->name ? next_sym->name : "<choice>");
-               } else if (stack->prop) {
+               } 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",
                                prop->file->name, prop->lineno,
                                sym->name ? sym->name : "<choice>",
                                next_sym->name ? next_sym->name : "<choice>");
-               } else if (sym_is_choice(sym)) {
-                       fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
-                               menu->file->name, menu->lineno,
+               } else if (stack->expr == &sym->rev_dep.expr) {
+                       fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
+                               prop->file->name, prop->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,
+               } else if (stack->expr == &sym->implied.expr) {
+                       fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n",
+                               prop->file->name, prop->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,
                                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 is selected by %s\n",
+                       fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %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.txt\n"
+               "subsection \"Kconfig recursive dependency limitations\"\n"
+               "\n");
+
        if (check_top == &cv_stack)
                dep_stack_remove();
 }
@@ -1215,7 +1152,7 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
        default:
                break;
        }
-       printf("Oops! How to check %d?\n", e->type);
+       fprintf(stderr, "Oops! How to check %d?\n", e->type);
        return NULL;
 }
 
@@ -1228,12 +1165,26 @@ 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)
+               if (prop->type == P_CHOICE || prop->type == P_SELECT ||
+                   prop->type == P_IMPLY)
                        continue;
                stack.prop = prop;
                sym2 = sym_check_expr_deps(prop->visible.expr);
@@ -1241,7 +1192,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;
@@ -1319,9 +1270,6 @@ struct symbol *sym_check_deps(struct symbol *sym)
                sym->flags &= ~SYMBOL_CHECK;
        }
 
-       if (sym2 && sym2 == sym)
-               sym2 = NULL;
-
        return sym2;
 }
 
@@ -1360,8 +1308,6 @@ 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:
@@ -1383,32 +1329,3 @@ 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);
-}