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.
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 | conf_warning("symbol value '%s' invalid for %s", | 227 | conf_warning("symbol value '%s' invalid for %s", |
| 228 | p, sym->name); | 228 | p, sym->name); |
| 229 | return 1; | 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 | case S_STRING: | 230 | case S_STRING: |
| 239 | if (*p++ != '"') | 231 | if (*p++ != '"') |
| 240 | break; | 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 | /* fall through */ | 245 | /* fall through */ |
| 254 | case S_INT: | 246 | case S_INT: |
| 255 | case S_HEX: | 247 | case S_HEX: |
| 256 | done: | ||
| 257 | if (sym_string_valid(sym, p)) { | 248 | if (sym_string_valid(sym, p)) { |
| 258 | sym->def[def].val = xstrdup(p); | 249 | sym->def[def].val = xstrdup(p); |
| 259 | sym->flags |= def_flags; | 250 | sym->flags |= def_flags; |
| @@ -434,17 +425,22 @@ load: · 174 unmodified lines | |||
| 434 | if (*p2 == '\r') | 425 | if (*p2 == '\r') |
| 435 | *p2 = 0; | 426 | *p2 = 0; |
| 436 | } | 427 | } |
| 437 | if (def == S_DEF_USER) { | 428 | |
| 438 | sym = sym_find(line + strlen(CONFIG_)); | 429 | sym = sym_find(line + strlen(CONFIG_)); |
| 439 | if (!sym) { | 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 | sym_add_change_count(1); | 440 | sym_add_change_count(1); |
| 441 | continue; | 441 | continue; |
| 442 | } | ||
| 443 | } else { | ||
| 444 | sym = sym_lookup(line + strlen(CONFIG_), 0); | ||
| 445 | if (sym->type == S_UNKNOWN) | ||
| 446 | sym->type = S_OTHER; | ||
| 447 | } | 442 | } |
| 443 | |||
| 448 | if (sym->flags & def_flags) { | 444 | if (sym->flags & def_flags) { |
| 449 | conf_warning("override: reassigning to symbol %s", sym->name); | 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 | const char *str; | 706 | const char *str; |
| 711 | 707 | ||
| 712 | switch (sym->type) { | 708 | switch (sym->type) { |
| 713 | case S_OTHER: | ||
| 714 | case S_UNKNOWN: | 709 | case S_UNKNOWN: |
| 715 | break; | 710 | break; |
| 716 | case S_STRING: | 711 | case S_STRING: |
| @@ -62,7 +62,7 @@ struct symbol_value { · 61 unmodified lines | |||
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | enum symbol_type { | 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 | /* enum values are used as index to symbol.def[] */ | 68 | /* enum values are used as index to symbol.def[] */ |
| @@ -131,7 +131,7 @@ struct symbol { · 62 unmodified lines | |||
| 131 | struct expr_value implied; | 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 | #define SYMBOL_CONST 0x0001 /* symbol is const */ | 136 | #define SYMBOL_CONST 0x0001 /* symbol is const */ |
| 137 | #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ | 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 | return "string"; | 61 | return "string"; |
| 62 | case S_UNKNOWN: | 62 | case S_UNKNOWN: |
| 63 | return "unknown"; | 63 | return "unknown"; |
| 64 | case S_OTHER: | ||
| 65 | break; | ||
| 66 | } | 64 | } |
| 67 | return "???"; | 65 | return "???"; |
| 68 | } | 66 | } |
| @@ -757,7 +755,6 @@ const char *sym_get_string_default(struct symbol *sym) · 688 unmodified lines | |||
| 757 | return str; | 755 | return str; |
| 758 | case S_STRING: | 756 | case S_STRING: |
| 759 | return str; | 757 | return str; |
| 760 | case S_OTHER: | ||
| 761 | case S_UNKNOWN: | 758 | case S_UNKNOWN: |
| 762 | break; | 759 | break; |
| 763 | } | 760 | } |