diff options
author | Roman Zippel <zippel@linux-m68k.org> | 2005-11-09 00:34:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-09 10:55:54 -0500 |
commit | c1a0f5e3c01d28b6782457bee5ae5ace3a9958ec (patch) | |
tree | a81f2f28e50013dad3b4c31f4dca4600b2909eb0 | |
parent | a02f0570ae201c495ee991b959bb974af18f35cc (diff) |
[PATCH] kconfig: stricter error checking for .config
Add some more checks during the parsing of .config, so that after parsing
sym_change_count reflects the correct state whether the .config is correct and
in sync with the Kconfig or if it needs saving.
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-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 | ||