diff options
| -rw-r--r-- | scripts/kconfig/confdata.c | 95 | ||||
| -rw-r--r-- | scripts/kconfig/lkc.h | 1 |
2 files changed, 77 insertions, 19 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 4bba6202b79e..ccd45130c482 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
| @@ -14,6 +14,12 @@ | |||
| 14 | #define LKC_DIRECT_LINK | 14 | #define LKC_DIRECT_LINK |
| 15 | #include "lkc.h" | 15 | #include "lkc.h" |
| 16 | 16 | ||
| 17 | static void conf_warning(const char *fmt, ...) | ||
| 18 | __attribute__ ((format (printf, 1, 2))); | ||
| 19 | |||
| 20 | static const char *conf_filename; | ||
| 21 | static int conf_lineno, conf_warnings, conf_unsaved; | ||
| 22 | |||
| 17 | const char conf_def_filename[] = ".config"; | 23 | const char conf_def_filename[] = ".config"; |
| 18 | 24 | ||
| 19 | const char conf_defname[] = "arch/$ARCH/defconfig"; | 25 | const char conf_defname[] = "arch/$ARCH/defconfig"; |
| @@ -27,6 +33,17 @@ const char *conf_confnames[] = { | |||
| 27 | NULL, | 33 | NULL, |
| 28 | }; | 34 | }; |
| 29 | 35 | ||
| 36 | static void conf_warning(const char *fmt, ...) | ||
| 37 | { | ||
| 38 | va_list ap; | ||
| 39 | va_start(ap, fmt); | ||
| 40 | fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno); | ||
| 41 | vfprintf(stderr, fmt, ap); | ||
| 42 | fprintf(stderr, "\n"); | ||
| 43 | va_end(ap); | ||
| 44 | conf_warnings++; | ||
| 45 | } | ||
| 46 | |||
| 30 | static char *conf_expand_value(const char *in) | 47 | static char *conf_expand_value(const char *in) |
| 31 | { | 48 | { |
| 32 | struct symbol *sym; | 49 | struct symbol *sym; |
| @@ -74,7 +91,6 @@ int conf_read_simple(const char *name) | |||
| 74 | FILE *in = NULL; | 91 | FILE *in = NULL; |
| 75 | char line[1024]; | 92 | char line[1024]; |
| 76 | char *p, *p2; | 93 | char *p, *p2; |
| 77 | int lineno = 0; | ||
| 78 | struct symbol *sym; | 94 | struct symbol *sym; |
| 79 | int i; | 95 | int i; |
| 80 | 96 | ||
| @@ -93,12 +109,18 @@ int conf_read_simple(const char *name) | |||
| 93 | } | 109 | } |
| 94 | } | 110 | } |
| 95 | } | 111 | } |
| 96 | |||
| 97 | if (!in) | 112 | if (!in) |
| 98 | return 1; | 113 | return 1; |
| 99 | 114 | ||
| 115 | conf_filename = name; | ||
| 116 | conf_lineno = 0; | ||
| 117 | conf_warnings = 0; | ||
| 118 | conf_unsaved = 0; | ||
| 119 | |||
| 100 | for_all_symbols(i, sym) { | 120 | for_all_symbols(i, sym) { |
| 101 | sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; | 121 | sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; |
| 122 | if (sym_is_choice(sym)) | ||
| 123 | sym->flags &= ~SYMBOL_NEW; | ||
| 102 | sym->flags &= ~SYMBOL_VALID; | 124 | sym->flags &= ~SYMBOL_VALID; |
| 103 | switch (sym->type) { | 125 | switch (sym->type) { |
| 104 | case S_INT: | 126 | case S_INT: |
| @@ -113,7 +135,7 @@ int conf_read_simple(const char *name) | |||
| 113 | } | 135 | } |
| 114 | 136 | ||
| 115 | while (fgets(line, sizeof(line), in)) { | 137 | while (fgets(line, sizeof(line), in)) { |
| 116 | lineno++; | 138 | conf_lineno++; |
| 117 | sym = NULL; | 139 | sym = NULL; |
| 118 | switch (line[0]) { | 140 | switch (line[0]) { |
| 119 | case '#': | 141 | case '#': |
| @@ -127,7 +149,10 @@ int conf_read_simple(const char *name) | |||
| 127 | continue; | 149 | continue; |
| 128 | sym = sym_find(line + 9); | 150 | sym = sym_find(line + 9); |
| 129 | if (!sym) { | 151 | if (!sym) { |
| 130 | fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9); | 152 | conf_warning("trying to assign nonexistent symbol %s", line + 9); |
| 153 | break; | ||
| 154 | } else if (!(sym->flags & SYMBOL_NEW)) { | ||
| 155 | conf_warning("trying to reassign symbol %s", sym->name); | ||
| 131 | break; | 156 | break; |
| 132 | } | 157 | } |
| 133 | switch (sym->type) { | 158 | switch (sym->type) { |
| @@ -141,8 +166,10 @@ int conf_read_simple(const char *name) | |||
| 141 | } | 166 | } |
| 142 | break; | 167 | break; |
| 143 | case 'C': | 168 | case 'C': |
| 144 | if (memcmp(line, "CONFIG_", 7)) | 169 | if (memcmp(line, "CONFIG_", 7)) { |
| 170 | conf_warning("unexpected data"); | ||
| 145 | continue; | 171 | continue; |
| 172 | } | ||
| 146 | p = strchr(line + 7, '='); | 173 | p = strchr(line + 7, '='); |
| 147 | if (!p) | 174 | if (!p) |
| 148 | continue; | 175 | continue; |
| @@ -152,7 +179,10 @@ int conf_read_simple(const char *name) | |||
| 152 | *p2 = 0; | 179 | *p2 = 0; |
| 153 | sym = sym_find(line + 7); | 180 | sym = sym_find(line + 7); |
| 154 | if (!sym) { | 181 | if (!sym) { |
| 155 | fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7); | 182 | conf_warning("trying to assign nonexistent symbol %s", line + 7); |
| 183 | break; | ||
| 184 | } else if (!(sym->flags & SYMBOL_NEW)) { | ||
| 185 | conf_warning("trying to reassign symbol %s", sym->name); | ||
| 156 | break; | 186 | break; |
| 157 | } | 187 | } |
| 158 | switch (sym->type) { | 188 | switch (sym->type) { |
| @@ -173,6 +203,7 @@ int conf_read_simple(const char *name) | |||
| 173 | sym->flags &= ~SYMBOL_NEW; | 203 | sym->flags &= ~SYMBOL_NEW; |
| 174 | break; | 204 | break; |
| 175 | } | 205 | } |
| 206 | conf_warning("symbol value '%s' invalid for %s", p, sym->name); | ||
| 176 | break; | 207 | break; |
| 177 | case S_STRING: | 208 | case S_STRING: |
| 178 | if (*p++ != '"') | 209 | if (*p++ != '"') |
| @@ -185,8 +216,8 @@ int conf_read_simple(const char *name) | |||
| 185 | memmove(p2, p2 + 1, strlen(p2)); | 216 | memmove(p2, p2 + 1, strlen(p2)); |
| 186 | } | 217 | } |
| 187 | if (!p2) { | 218 | if (!p2) { |
| 188 | fprintf(stderr, "%s:%d: invalid string found\n", name, lineno); | 219 | conf_warning("invalid string found"); |
| 189 | exit(1); | 220 | continue; |
| 190 | } | 221 | } |
| 191 | case S_INT: | 222 | case S_INT: |
| 192 | case S_HEX: | 223 | case S_HEX: |
| @@ -194,8 +225,8 @@ int conf_read_simple(const char *name) | |||
| 194 | sym->user.val = strdup(p); | 225 | sym->user.val = strdup(p); |
| 195 | sym->flags &= ~SYMBOL_NEW; | 226 | sym->flags &= ~SYMBOL_NEW; |
| 196 | } else { | 227 | } else { |
| 197 | fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); | 228 | conf_warning("symbol value '%s' invalid for %s", p, sym->name); |
| 198 | exit(1); | 229 | continue; |
| 199 | } | 230 | } |
| 200 | break; | 231 | break; |
| 201 | default: | 232 | default: |
| @@ -205,6 +236,7 @@ int conf_read_simple(const char *name) | |||
| 205 | case '\n': | 236 | case '\n': |
| 206 | break; | 237 | break; |
| 207 | default: | 238 | default: |
| 239 | conf_warning("unexpected data"); | ||
| 208 | continue; | 240 | continue; |
| 209 | } | 241 | } |
| 210 | if (sym && sym_is_choice_value(sym)) { | 242 | if (sym && sym_is_choice_value(sym)) { |
| @@ -213,17 +245,20 @@ int conf_read_simple(const char *name) | |||
| 213 | case no: | 245 | case no: |
| 214 | break; | 246 | break; |
| 215 | case mod: | 247 | case mod: |
| 216 | if (cs->user.tri == yes) | 248 | if (cs->user.tri == yes) { |
| 217 | /* warn? */; | 249 | conf_warning("%s creates inconsistent choice state", sym->name); |
| 250 | cs->flags |= SYMBOL_NEW; | ||
| 251 | } | ||
| 218 | break; | 252 | break; |
| 219 | case yes: | 253 | case yes: |
| 220 | if (cs->user.tri != no) | 254 | if (cs->user.tri != no) { |
| 221 | /* warn? */; | 255 | conf_warning("%s creates inconsistent choice state", sym->name); |
| 222 | cs->user.val = sym; | 256 | cs->flags |= SYMBOL_NEW; |
| 257 | } else | ||
| 258 | cs->user.val = sym; | ||
| 223 | break; | 259 | break; |
| 224 | } | 260 | } |
| 225 | cs->user.tri = E_OR(cs->user.tri, sym->user.tri); | 261 | cs->user.tri = E_OR(cs->user.tri, sym->user.tri); |
| 226 | cs->flags &= ~SYMBOL_NEW; | ||
| 227 | } | 262 | } |
| 228 | } | 263 | } |
| 229 | fclose(in); | 264 | fclose(in); |
| @@ -245,6 +280,28 @@ int conf_read(const char *name) | |||
| 245 | 280 | ||
| 246 | for_all_symbols(i, sym) { | 281 | for_all_symbols(i, sym) { |
| 247 | sym_calc_value(sym); | 282 | sym_calc_value(sym); |
| 283 | if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) | ||
| 284 | goto sym_ok; | ||
| 285 | if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { | ||
| 286 | /* check that calculated value agrees with saved value */ | ||
| 287 | switch (sym->type) { | ||
| 288 | case S_BOOLEAN: | ||
| 289 | case S_TRISTATE: | ||
| 290 | if (sym->user.tri != sym_get_tristate_value(sym)) | ||
| 291 | break; | ||
| 292 | if (!sym_is_choice(sym)) | ||
| 293 | goto sym_ok; | ||
| 294 | default: | ||
| 295 | if (!strcmp(sym->curr.val, sym->user.val)) | ||
| 296 | goto sym_ok; | ||
| 297 | break; | ||
| 298 | } | ||
| 299 | } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) | ||
| 300 | /* no previous value and not saved */ | ||
| 301 | goto sym_ok; | ||
| 302 | conf_unsaved++; | ||
| 303 | /* maybe print value in verbose mode... */ | ||
| 304 | sym_ok: | ||
| 248 | if (sym_has_value(sym) && !sym_is_choice_value(sym)) { | 305 | if (sym_has_value(sym) && !sym_is_choice_value(sym)) { |
| 249 | if (sym->visible == no) | 306 | if (sym->visible == no) |
| 250 | sym->flags |= SYMBOL_NEW; | 307 | sym->flags |= SYMBOL_NEW; |
| @@ -252,8 +309,10 @@ int conf_read(const char *name) | |||
| 252 | case S_STRING: | 309 | case S_STRING: |
| 253 | case S_INT: | 310 | case S_INT: |
| 254 | case S_HEX: | 311 | case S_HEX: |
| 255 | if (!sym_string_within_range(sym, sym->user.val)) | 312 | if (!sym_string_within_range(sym, sym->user.val)) { |
| 256 | sym->flags |= SYMBOL_NEW; | 313 | sym->flags |= SYMBOL_NEW; |
| 314 | sym->flags &= ~SYMBOL_VALID; | ||
| 315 | } | ||
| 257 | default: | 316 | default: |
| 258 | break; | 317 | break; |
| 259 | } | 318 | } |
| @@ -266,7 +325,7 @@ int conf_read(const char *name) | |||
| 266 | sym->flags |= e->right.sym->flags & SYMBOL_NEW; | 325 | sym->flags |= e->right.sym->flags & SYMBOL_NEW; |
| 267 | } | 326 | } |
| 268 | 327 | ||
| 269 | sym_change_count = 1; | 328 | sym_change_count = conf_warnings && conf_unsaved; |
| 270 | 329 | ||
| 271 | return 0; | 330 | return 0; |
| 272 | } | 331 | } |
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index ca02eb42eeb3..527f60c99c50 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h | |||
| @@ -61,7 +61,6 @@ char *zconf_curname(void); | |||
| 61 | 61 | ||
| 62 | /* confdata.c */ | 62 | /* confdata.c */ |
| 63 | extern const char conf_def_filename[]; | 63 | extern const char conf_def_filename[]; |
| 64 | extern char conf_filename[]; | ||
| 65 | 64 | ||
| 66 | char *conf_get_default_confname(void); | 65 | char *conf_get_default_confname(void); |
| 67 | 66 | ||
