The S_OTHER type could be set only when conf_read_simple() is reading include/config/auto.conf file. For example, CONFIG_FOO=y exists in include/config/auto.conf but it is missing from the currently parsed Kconfig files, sym_lookup() allocates a new symbol, and sets its type to S_OTHER. Strangely, it will be set to S_STRING by conf_set_sym_val() a few lines below while it is obviously bool or tristate type. On the other hand, when CONFIG_BAR="bar" is being dropped from include/config/auto.conf, its type remains S_OTHER. Because for_all_symbols() omits S_OTHER symbols, conf_touch_deps() misses to touch include/config/bar.h This behavior has been a pretty mystery for me, and digging the git histroy did not help. At least, touching depfiles is broken for string type symbols. I removed S_OTHER entirely, and reimplemented it more simply. If CONFIG_FOO was visible in the previous syncconfig, but is missing now, what we want to do is quite simple; just call conf_touch_dep() to touch include/config/foo.h instead of allocating a new symbol data.
Showing the changes to scripts (3 of 3 files). Show all
Unified · Split
| @@ -227,14 +227,6 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) · 226 unmodified lines | ||
| 227 | 227 | conf_warning("symbol value '%s' invalid for %s", |
| 228 | 228 | p, sym->name); |
| 229 | 229 | return 1; |
| 230 | − case S_OTHER: | |
| 231 | − if (*p != '"') { | |
| 232 | − for (p2 = p; *p2 && !isspace(*p2); p2++) | |
| 233 | − ; | |
| 234 | − sym->type = S_STRING; | |
| 235 | − goto done; | |
| 236 | − } | |
| 237 | − /* fall through */ | |
| 238 | 230 | case S_STRING: |
| 239 | 231 | if (*p++ != '"') |
| 240 | 232 | break; |
| @@ -253,7 +245,6 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) · 12 unmodified lines | ||
| 253 | 245 | /* fall through */ |
| 254 | 246 | case S_INT: |
| 255 | 247 | case S_HEX: |
| 256 | − done: | |
| 257 | 248 | if (sym_string_valid(sym, p)) { |
| 258 | 249 | sym->def[def].val = xstrdup(p); |
| 259 | 250 | sym->flags |= def_flags; |
| @@ -434,17 +425,22 @@ load: · 174 unmodified lines | ||
| 434 | 425 | if (*p2 == '\r') |
| 435 | 426 | *p2 = 0; |
| 436 | 427 | } |
| 437 | − if (def == S_DEF_USER) { | |
| 438 | − sym = sym_find(line + strlen(CONFIG_)); | |
| 439 | − if (!sym) { | |
| 428 | + | |
| 429 | + sym = sym_find(line + strlen(CONFIG_)); | |
| 430 | + if (!sym) { | |
| 431 | + if (def == S_DEF_AUTO) | |
| 432 | + /* | |
| 433 | + * Reading from include/config/auto.conf | |
| 434 | + * If CONFIG_FOO previously existed in | |
| 435 | + * auto.conf but it is missing now, | |
| 436 | + * include/config/foo.h must be touched. | |
| 437 | + */ | |
| 438 | + conf_touch_dep(line + strlen(CONFIG_)); | |
| 439 | + else | |
| 440 | 440 | sym_add_change_count(1); |
| 441 | − continue; | |
| 442 | − } | |
| 443 | − } else { | |
| 444 | − sym = sym_lookup(line + strlen(CONFIG_), 0); | |
| 445 | − if (sym->type == S_UNKNOWN) | |
| 446 | − sym->type = S_OTHER; | |
| 441 | + continue; | |
| 447 | 442 | } |
| 443 | + | |
| 448 | 444 | if (sym->flags & def_flags) { |
| 449 | 445 | conf_warning("override: reassigning to symbol %s", sym->name); |
| 450 | 446 | } |
| @@ -710,7 +706,6 @@ static void conf_write_symbol(FILE *fp, struct symbol *sym, · 259 unmodified lines | ||
| 710 | 706 | const char *str; |
| 711 | 707 | |
| 712 | 708 | switch (sym->type) { |
| 713 | − case S_OTHER: | |
| 714 | 709 | case S_UNKNOWN: |
| 715 | 710 | break; |
| 716 | 711 | case S_STRING: |
| @@ -62,7 +62,7 @@ struct symbol_value { · 61 unmodified lines | ||
| 62 | 62 | }; |
| 63 | 63 | |
| 64 | 64 | enum symbol_type { |
| 65 | − S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER | |
| 65 | + S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING | |
| 66 | 66 | }; |
| 67 | 67 | |
| 68 | 68 | /* enum values are used as index to symbol.def[] */ |
| @@ -131,7 +131,7 @@ struct symbol { · 62 unmodified lines | ||
| 131 | 131 | struct expr_value implied; |
| 132 | 132 | }; |
| 133 | 133 | |
| 134 | −#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) | |
| 134 | +#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) | |
| 135 | 135 | |
| 136 | 136 | #define SYMBOL_CONST 0x0001 /* symbol is const */ |
| 137 | 137 | #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ |
| @@ -61,8 +61,6 @@ const char *sym_type_name(enum symbol_type type) · 60 unmodified lines | ||
| 61 | 61 | return "string"; |
| 62 | 62 | case S_UNKNOWN: |
| 63 | 63 | return "unknown"; |
| 64 | − case S_OTHER: | |
| 65 | − break; | |
| 66 | 64 | } |
| 67 | 65 | return "???"; |
| 68 | 66 | } |
| @@ -757,7 +755,6 @@ const char *sym_get_string_default(struct symbol *sym) · 688 unmodified lines | ||
| 757 | 755 | return str; |
| 758 | 756 | case S_STRING: |
| 759 | 757 | return str; |
| 760 | − case S_OTHER: | |
| 761 | 758 | case S_UNKNOWN: |
| 762 | 759 | break; |
| 763 | 760 | } |