^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <regex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sys/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "lkc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct symbol symbol_yes = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) .name = "y",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) .curr = { "y", yes },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) .flags = SYMBOL_CONST|SYMBOL_VALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct symbol symbol_mod = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) .name = "m",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) .curr = { "m", mod },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) .flags = SYMBOL_CONST|SYMBOL_VALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct symbol symbol_no = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .name = "n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .curr = { "n", no },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .flags = SYMBOL_CONST|SYMBOL_VALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static struct symbol symbol_empty = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .name = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .curr = { "", no },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .flags = SYMBOL_VALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct symbol *sym_defconfig_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct symbol *modules_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static tristate modules_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) enum symbol_type sym_get_type(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) enum symbol_type type = sym->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (type == S_TRISTATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (sym_is_choice_value(sym) && sym->visible == yes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) type = S_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) else if (modules_val == no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) type = S_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) const char *sym_type_name(enum symbol_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) case S_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return "bool";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) case S_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return "tristate";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) case S_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return "integer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) case S_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return "hex";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case S_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return "string";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case S_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return "???";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct property *sym_get_choice_prop(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) for_all_choices(sym, prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static struct property *sym_get_default_prop(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) for_all_defaults(sym, prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) prop->visible.tri = expr_calc_value(prop->visible.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (prop->visible.tri != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct property *sym_get_range_prop(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) for_all_properties(sym, prop, P_RANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) prop->visible.tri = expr_calc_value(prop->visible.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (prop->visible.tri != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static long long sym_get_range_val(struct symbol *sym, int base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) sym_calc_value(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) switch (sym->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case S_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) base = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) case S_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) base = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return strtoll(sym->curr.val, NULL, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void sym_validate_range(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) long long val, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) char str[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) switch (sym->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) case S_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) base = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) case S_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) base = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) prop = sym_get_range_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) val = strtoll(sym->curr.val, NULL, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) val2 = sym_get_range_val(prop->expr->left.sym, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (val >= val2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) val2 = sym_get_range_val(prop->expr->right.sym, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (val <= val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (sym->type == S_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) sprintf(str, "%lld", val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) sprintf(str, "0x%llx", val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) sym->curr.val = xstrdup(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static void sym_set_changed(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) sym->flags |= SYMBOL_CHANGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) for (prop = sym->prop; prop; prop = prop->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (prop->menu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) prop->menu->flags |= MENU_CHANGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static void sym_set_all_changed(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) for_all_symbols(i, sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) sym_set_changed(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static void sym_calc_visibility(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct symbol *choice_sym = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) tristate tri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* any prompt visible? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) tri = no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (sym_is_choice_value(sym))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) choice_sym = prop_get_symbol(sym_get_choice_prop(sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) for_all_prompts(sym, prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) prop->visible.tri = expr_calc_value(prop->visible.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * Tristate choice_values with visibility 'mod' are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * not visible if the corresponding choice's value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * 'yes'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (choice_sym && sym->type == S_TRISTATE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) prop->visible.tri == mod && choice_sym->curr.tri == yes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) prop->visible.tri = no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) tri = EXPR_OR(tri, prop->visible.tri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) tri = yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (sym->visible != tri) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) sym->visible = tri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) sym_set_changed(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (sym_is_choice_value(sym))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* defaulting to "yes" if no explicit "depends on" are given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) tri = yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (sym->dir_dep.expr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) tri = expr_calc_value(sym->dir_dep.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) tri = yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (sym->dir_dep.tri != tri) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) sym->dir_dep.tri = tri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) sym_set_changed(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) tri = no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (sym->rev_dep.expr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) tri = expr_calc_value(sym->rev_dep.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) tri = yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (sym->rev_dep.tri != tri) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) sym->rev_dep.tri = tri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sym_set_changed(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) tri = no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (sym->implied.expr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) tri = expr_calc_value(sym->implied.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) tri = yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (sym->implied.tri != tri) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) sym->implied.tri = tri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) sym_set_changed(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * Find the default symbol for a choice.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * First try the default values for the choice symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * Next locate the first visible choice value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * Return NULL if none was found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct symbol *sym_choice_default(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct symbol *def_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct expr *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* any of the defaults visible? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) for_all_defaults(sym, prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) prop->visible.tri = expr_calc_value(prop->visible.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (prop->visible.tri == no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) def_sym = prop_get_symbol(prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (def_sym->visible != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return def_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* just get the first visible value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) prop = sym_get_choice_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) expr_list_for_each_sym(prop->expr, e, def_sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (def_sym->visible != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return def_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* failed to locate any defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static struct symbol *sym_calc_choice(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct symbol *def_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct expr *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* first calculate all choice values' visibilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) flags = sym->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) prop = sym_get_choice_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) expr_list_for_each_sym(prop->expr, e, def_sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) sym_calc_visibility(def_sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (def_sym->visible != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) flags &= def_sym->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) sym->flags &= flags | ~SYMBOL_DEF_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* is the user choice visible? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) def_sym = sym->def[S_DEF_USER].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (def_sym && def_sym->visible != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return def_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) def_sym = sym_choice_default(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (def_sym == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* no choice? reset tristate value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sym->curr.tri = no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return def_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static void sym_warn_unmet_dep(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct gstr gs = str_new();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) str_printf(&gs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) "\nWARNING: unmet direct dependencies detected for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) str_printf(&gs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) " Depends on [%c]: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) sym->dir_dep.tri == mod ? 'm' : 'n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) expr_gstr_print(sym->dir_dep.expr, &gs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) str_printf(&gs, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) " Selected by [y]:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) " Selected by [m]:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) fputs(str_get(&gs), stderr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) void sym_calc_value(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct symbol_value newval, oldval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct expr *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (sym->flags & SYMBOL_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (sym_is_choice_value(sym) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) sym->flags &= ~SYMBOL_NEED_SET_CHOICE_VALUES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) prop = sym_get_choice_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sym_calc_value(prop_get_symbol(prop));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) sym->flags |= SYMBOL_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) oldval = sym->curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) switch (sym->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case S_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) case S_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case S_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) newval = symbol_empty.curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case S_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case S_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) newval = symbol_no.curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) sym->curr.val = sym->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) sym->curr.tri = no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) sym->flags &= ~SYMBOL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) sym_calc_visibility(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (sym->visible != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) sym->flags |= SYMBOL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* set default if recursively called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) sym->curr = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) switch (sym_get_type(sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) case S_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) case S_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (sym_is_choice_value(sym) && sym->visible == yes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) prop = sym_get_choice_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (sym->visible != no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* if the symbol is visible use the user value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * if available, otherwise try the default value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (sym_has_value(sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) sym->visible);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) goto calc_newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (sym->rev_dep.tri != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) sym->flags |= SYMBOL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (!sym_is_choice(sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) prop = sym_get_default_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) newval.tri = EXPR_AND(expr_calc_value(prop->expr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) prop->visible.tri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (newval.tri != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) sym->flags |= SYMBOL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (sym->implied.tri != no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) sym->flags |= SYMBOL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) newval.tri = EXPR_OR(newval.tri, sym->implied.tri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) newval.tri = EXPR_AND(newval.tri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) sym->dir_dep.tri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) calc_newval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (sym->dir_dep.tri < sym->rev_dep.tri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) sym_warn_unmet_dep(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) newval.tri = yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) case S_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) case S_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) case S_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (sym->visible != no && sym_has_value(sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) newval.val = sym->def[S_DEF_USER].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) prop = sym_get_default_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct symbol *ds = prop_get_symbol(prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (ds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) sym->flags |= SYMBOL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) sym_calc_value(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) newval.val = ds->curr.val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) sym->curr = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (sym_is_choice(sym) && newval.tri == yes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) sym->curr.val = sym_calc_choice(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) sym_validate_range(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) sym_set_changed(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (modules_sym == sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) sym_set_all_changed();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) modules_val = modules_sym->curr.tri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (sym_is_choice(sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct symbol *choice_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) prop = sym_get_choice_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) expr_list_for_each_sym(prop->expr, e, choice_sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if ((sym->flags & SYMBOL_WRITE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) choice_sym->visible != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) choice_sym->flags |= SYMBOL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (sym->flags & SYMBOL_CHANGED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) sym_set_changed(choice_sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (sym->flags & SYMBOL_NO_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) sym->flags &= ~SYMBOL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) set_all_choice_values(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) void sym_clear_all_valid(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) for_all_symbols(i, sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) sym->flags &= ~SYMBOL_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) sym_add_change_count(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) sym_calc_value(modules_sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) bool sym_tristate_within_range(struct symbol *sym, tristate val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int type = sym_get_type(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (sym->visible == no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (type != S_BOOLEAN && type != S_TRISTATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (type == S_BOOLEAN && val == mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (sym->visible <= sym->rev_dep.tri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (sym_is_choice_value(sym) && sym->visible == yes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return val == yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return val >= sym->rev_dep.tri && val <= sym->visible;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) bool sym_set_tristate_value(struct symbol *sym, tristate val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) tristate oldval = sym_get_tristate_value(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (oldval != val && !sym_tristate_within_range(sym, val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (!(sym->flags & SYMBOL_DEF_USER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) sym->flags |= SYMBOL_DEF_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) sym_set_changed(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * setting a choice value also resets the new flag of the choice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * symbol and all other choice values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (sym_is_choice_value(sym) && val == yes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct expr *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) cs->def[S_DEF_USER].val = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) cs->flags |= SYMBOL_DEF_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) prop = sym_get_choice_prop(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) for (e = prop->expr; e; e = e->left.expr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (e->right.sym->visible != no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) e->right.sym->flags |= SYMBOL_DEF_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) sym->def[S_DEF_USER].tri = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (oldval != val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) sym_clear_all_valid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) tristate sym_toggle_tristate_value(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) tristate oldval, newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) oldval = newval = sym_get_tristate_value(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) switch (newval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) newval = mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) case mod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) newval = yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) case yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) newval = no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (sym_set_tristate_value(sym, newval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) } while (oldval != newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) bool sym_string_valid(struct symbol *sym, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) signed char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) switch (sym->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) case S_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) case S_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ch = *str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (ch == '-')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) ch = *str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (!isdigit(ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (ch == '0' && *str != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) while ((ch = *str++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (!isdigit(ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) case S_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) str += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ch = *str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (!isxdigit(ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) } while ((ch = *str++));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) case S_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) case S_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) switch (str[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) case 'y': case 'Y':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) case 'm': case 'M':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) case 'n': case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) bool sym_string_within_range(struct symbol *sym, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) long long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) switch (sym->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) case S_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return sym_string_valid(sym, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) case S_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!sym_string_valid(sym, str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) prop = sym_get_range_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) val = strtoll(str, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) val <= sym_get_range_val(prop->expr->right.sym, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) case S_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (!sym_string_valid(sym, str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) prop = sym_get_range_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) val = strtoll(str, NULL, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) val <= sym_get_range_val(prop->expr->right.sym, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) case S_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) case S_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) switch (str[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) case 'y': case 'Y':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return sym_tristate_within_range(sym, yes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) case 'm': case 'M':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return sym_tristate_within_range(sym, mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) case 'n': case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return sym_tristate_within_range(sym, no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) bool sym_set_string_value(struct symbol *sym, const char *newval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) const char *oldval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) char *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) switch (sym->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) case S_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) case S_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) switch (newval[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) case 'y': case 'Y':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return sym_set_tristate_value(sym, yes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) case 'm': case 'M':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return sym_set_tristate_value(sym, mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) case 'n': case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return sym_set_tristate_value(sym, no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (!sym_string_within_range(sym, newval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (!(sym->flags & SYMBOL_DEF_USER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) sym->flags |= SYMBOL_DEF_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) sym_set_changed(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) oldval = sym->def[S_DEF_USER].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) size = strlen(newval) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) size += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) sym->def[S_DEF_USER].val = val = xmalloc(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) *val++ = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) *val++ = 'x';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) } else if (!oldval || strcmp(oldval, newval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) sym->def[S_DEF_USER].val = val = xmalloc(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) strcpy(val, newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) free((void *)oldval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) sym_clear_all_valid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * Find the default value associated to a symbol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * For tristate symbol handle the modules=n case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * in which case "m" becomes "y".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * If the symbol does not have any default then fallback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * to the fixed default values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) const char *sym_get_string_default(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct symbol *ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) const char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) tristate val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) sym_calc_visibility(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) sym_calc_value(modules_sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) val = symbol_no.curr.tri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) str = symbol_empty.curr.val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* If symbol has a default value look it up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) prop = sym_get_default_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (prop != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) switch (sym->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) case S_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) case S_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* The visibility may limit the value from yes => mod */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * The following fails to handle the situation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * where a default value is further limited by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * the valid range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ds = prop_get_symbol(prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (ds != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) sym_calc_value(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) str = (const char *)ds->curr.val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* Handle select statements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) val = EXPR_OR(val, sym->rev_dep.tri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* transpose mod to yes if modules are not enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (val == mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) val = yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* transpose mod to yes if type is bool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (sym->type == S_BOOLEAN && val == mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) val = yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /* adjust the default value if this symbol is implied by another */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (val < sym->implied.tri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) val = sym->implied.tri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) switch (sym->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) case S_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case S_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) case no: return "n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) case mod: return "m";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) case yes: return "y";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) case S_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) case S_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) case S_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) case S_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) const char *sym_get_string_value(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) tristate val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) switch (sym->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) case S_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) case S_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) val = sym_get_tristate_value(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) case no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return "n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) case mod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) sym_calc_value(modules_sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return (modules_sym->curr.tri == no) ? "n" : "m";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) case yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return "y";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return (const char *)sym->curr.val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) bool sym_is_changeable(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return sym->visible > sym->rev_dep.tri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) static unsigned strhash(const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /* fnv32 hash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) unsigned hash = 2166136261U;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) for (; *s; s++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) hash = (hash ^ *s) * 0x01000193;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct symbol *sym_lookup(const char *name, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct symbol *symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) char *new_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) int hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (name[0] && !name[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) switch (name[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case 'y': return &symbol_yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) case 'm': return &symbol_mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case 'n': return &symbol_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) hash = strhash(name) % SYMBOL_HASHSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (symbol->name &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) !strcmp(symbol->name, name) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) (flags ? symbol->flags & flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) new_name = xstrdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) new_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) hash = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) symbol = xmalloc(sizeof(*symbol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) memset(symbol, 0, sizeof(*symbol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) symbol->name = new_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) symbol->type = S_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) symbol->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) symbol->next = symbol_hash[hash];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) symbol_hash[hash] = symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct symbol *sym_find(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct symbol *symbol = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) int hash = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (name[0] && !name[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) switch (name[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) case 'y': return &symbol_yes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) case 'm': return &symbol_mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) case 'n': return &symbol_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) hash = strhash(name) % SYMBOL_HASHSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (symbol->name &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) !strcmp(symbol->name, name) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) !(symbol->flags & SYMBOL_CONST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) const char *sym_escape_string_value(const char *in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) size_t reslen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) char *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) size_t l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) reslen = strlen(in) + strlen("\"\"") + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) p = in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) l = strcspn(p, "\"\\");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) p += l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (p[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) reslen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) res = xmalloc(reslen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) res[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) strcat(res, "\"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) p = in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) l = strcspn(p, "\"\\");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) strncat(res, p, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) p += l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (p[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) strcat(res, "\\");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) strncat(res, p++, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) strcat(res, "\"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct sym_match {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) off_t so, eo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /* Compare matched symbols as thus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * - first, symbols that match exactly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * - then, alphabetical sort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static int sym_rel_comp(const void *sym1, const void *sym2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) const struct sym_match *s1 = sym1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) const struct sym_match *s2 = sym2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int exact1, exact2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* Exact match:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * - if matched length on symbol s1 is the length of that symbol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * then this symbol should come first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * - if matched length on symbol s2 is the length of that symbol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * then this symbol should come first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) * Note: since the search can be a regexp, both symbols may match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) * exactly; if this is the case, we can't decide which comes first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) * and we fallback to sorting alphabetically.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) exact1 = (s1->eo - s1->so) == strlen(s1->sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) exact2 = (s2->eo - s2->so) == strlen(s2->sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (exact1 && !exact2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (!exact1 && exact2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /* As a fallback, sort symbols alphabetically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) return strcmp(s1->sym->name, s2->sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) struct symbol **sym_re_search(const char *pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) struct symbol *sym, **sym_arr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct sym_match *sym_match_arr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) int i, cnt, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) regex_t re;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) regmatch_t match[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) cnt = size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) /* Skip if empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (strlen(pattern) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) for_all_symbols(i, sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (sym->flags & SYMBOL_CONST || !sym->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (regexec(&re, sym->name, 1, match, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (cnt >= size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) void *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) size += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) tmp = realloc(sym_match_arr, size * sizeof(struct sym_match));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) goto sym_re_search_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) sym_match_arr = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) sym_calc_value(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /* As regexec returned 0, we know we have a match, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * we can use match[0].rm_[se]o without further checks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) sym_match_arr[cnt].so = match[0].rm_so;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) sym_match_arr[cnt].eo = match[0].rm_eo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) sym_match_arr[cnt++].sym = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (sym_match_arr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) sym_arr = malloc((cnt+1) * sizeof(struct symbol *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (!sym_arr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) goto sym_re_search_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) for (i = 0; i < cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) sym_arr[i] = sym_match_arr[i].sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) sym_arr[cnt] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) sym_re_search_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) /* sym_match_arr can be NULL if no match, but free(NULL) is OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) free(sym_match_arr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) regfree(&re);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return sym_arr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * When we check for recursive dependencies we use a stack to save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * current state so we can print out relevant info to user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * The entries are located on the call stack so no need to free memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * Note insert() remove() must always match to properly clear the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) static struct dep_stack {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct dep_stack *prev, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct expr **expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) } *check_top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) memset(stack, 0, sizeof(*stack));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (check_top)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) check_top->next = stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) stack->prev = check_top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) stack->sym = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) check_top = stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static void dep_stack_remove(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) check_top = check_top->prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (check_top)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) check_top->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * Called when we have detected a recursive dependency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * check_top point to the top of the stact so we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * the ->prev pointer to locate the bottom of the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) static void sym_check_print_recursive(struct symbol *last_sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct dep_stack *stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct symbol *sym, *next_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct menu *menu = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct dep_stack cv_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (sym_is_choice_value(last_sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) dep_stack_insert(&cv_stack, last_sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) for (stack = check_top; stack != NULL; stack = stack->prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (stack->sym == last_sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (!stack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) fprintf(stderr, "unexpected recursive dependency error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) for (; stack; stack = stack->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) sym = stack->sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) next_sym = stack->next ? stack->next->sym : last_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) prop = stack->prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (prop == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) prop = stack->sym->prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) /* for choice values find the menu entry (used below) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) for (prop = sym->prop; prop; prop = prop->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) menu = prop->menu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (prop->menu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (stack->sym == last_sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) prop->file->name, prop->lineno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (sym_is_choice(sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) menu->file->name, menu->lineno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) sym->name ? sym->name : "<choice>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) next_sym->name ? next_sym->name : "<choice>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) } else if (sym_is_choice_value(sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) menu->file->name, menu->lineno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) sym->name ? sym->name : "<choice>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) next_sym->name ? next_sym->name : "<choice>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) } else if (stack->expr == &sym->dir_dep.expr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) prop->file->name, prop->lineno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) sym->name ? sym->name : "<choice>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) next_sym->name ? next_sym->name : "<choice>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) } else if (stack->expr == &sym->rev_dep.expr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) prop->file->name, prop->lineno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) sym->name ? sym->name : "<choice>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) next_sym->name ? next_sym->name : "<choice>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) } else if (stack->expr == &sym->implied.expr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) prop->file->name, prop->lineno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) sym->name ? sym->name : "<choice>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) next_sym->name ? next_sym->name : "<choice>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) } else if (stack->expr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) prop->file->name, prop->lineno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) sym->name ? sym->name : "<choice>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) prop_get_type_name(prop->type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) next_sym->name ? next_sym->name : "<choice>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) prop->file->name, prop->lineno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) sym->name ? sym->name : "<choice>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) prop_get_type_name(prop->type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) next_sym->name ? next_sym->name : "<choice>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) "For a resolution refer to Documentation/kbuild/kconfig-language.rst\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) "subsection \"Kconfig recursive dependency limitations\"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (check_top == &cv_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) dep_stack_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static struct symbol *sym_check_expr_deps(struct expr *e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) switch (e->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) case E_OR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) case E_AND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) sym = sym_check_expr_deps(e->left.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return sym_check_expr_deps(e->right.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) case E_NOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return sym_check_expr_deps(e->left.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) case E_EQUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) case E_GEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) case E_GTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) case E_LEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) case E_LTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) case E_UNEQUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) sym = sym_check_deps(e->left.sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return sym_check_deps(e->right.sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) case E_SYMBOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return sym_check_deps(e->left.sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) fprintf(stderr, "Oops! How to check %d?\n", e->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /* return NULL when dependencies are OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static struct symbol *sym_check_sym_deps(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) struct symbol *sym2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct dep_stack stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) dep_stack_insert(&stack, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) stack.expr = &sym->dir_dep.expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) sym2 = sym_check_expr_deps(sym->dir_dep.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (sym2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) stack.expr = &sym->rev_dep.expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) sym2 = sym_check_expr_deps(sym->rev_dep.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (sym2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) stack.expr = &sym->implied.expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) sym2 = sym_check_expr_deps(sym->implied.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (sym2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) stack.expr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) for (prop = sym->prop; prop; prop = prop->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (prop->type == P_CHOICE || prop->type == P_SELECT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) prop->type == P_IMPLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) stack.prop = prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) sym2 = sym_check_expr_deps(prop->visible.expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) if (sym2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (prop->type != P_DEFAULT || sym_is_choice(sym))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) stack.expr = &prop->expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) sym2 = sym_check_expr_deps(prop->expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (sym2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) stack.expr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) dep_stack_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) return sym2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) static struct symbol *sym_check_choice_deps(struct symbol *choice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) struct symbol *sym, *sym2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct expr *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) struct dep_stack stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) dep_stack_insert(&stack, choice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) prop = sym_get_choice_prop(choice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) expr_list_for_each_sym(prop->expr, e, sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) sym2 = sym_check_sym_deps(choice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) choice->flags &= ~SYMBOL_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (sym2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) expr_list_for_each_sym(prop->expr, e, sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) sym2 = sym_check_sym_deps(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (sym2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) expr_list_for_each_sym(prop->expr, e, sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) sym->flags &= ~SYMBOL_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (sym2 && sym_is_choice_value(sym2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) sym2 = choice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) dep_stack_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return sym2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct symbol *sym_check_deps(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) struct symbol *sym2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (sym->flags & SYMBOL_CHECK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) sym_check_print_recursive(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (sym->flags & SYMBOL_CHECKED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (sym_is_choice_value(sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) struct dep_stack stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) /* for choice groups start the check with main choice symbol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) dep_stack_insert(&stack, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) prop = sym_get_choice_prop(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) sym2 = sym_check_deps(prop_get_symbol(prop));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) dep_stack_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) } else if (sym_is_choice(sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) sym2 = sym_check_choice_deps(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) sym2 = sym_check_sym_deps(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) sym->flags &= ~SYMBOL_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return sym2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) struct symbol *prop_get_symbol(struct property *prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (prop->expr && (prop->expr->type == E_SYMBOL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) prop->expr->type == E_LIST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) return prop->expr->left.sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) const char *prop_get_type_name(enum prop_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) case P_PROMPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return "prompt";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) case P_COMMENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) return "comment";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) case P_MENU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) return "menu";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) case P_DEFAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) return "default";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) case P_CHOICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return "choice";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) case P_SELECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return "select";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) case P_IMPLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return "imply";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) case P_RANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return "range";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) case P_SYMBOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return "symbol";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) case P_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }