aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig/confdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kconfig/confdata.c')
-rw-r--r--scripts/kconfig/confdata.c95
1 files changed, 77 insertions, 18 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
17static void conf_warning(const char *fmt, ...)
18 __attribute__ ((format (printf, 1, 2)));
19
20static const char *conf_filename;
21static int conf_lineno, conf_warnings, conf_unsaved;
22
17const char conf_def_filename[] = ".config"; 23const char conf_def_filename[] = ".config";
18 24
19const char conf_defname[] = "arch/$ARCH/defconfig"; 25const char conf_defname[] = "arch/$ARCH/defconfig";
@@ -27,6 +33,17 @@ const char *conf_confnames[] = {
27 NULL, 33 NULL,
28}; 34};
29 35
36static 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
30static char *conf_expand_value(const char *in) 47static 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}