mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-21 06:24:12 +00:00
[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>
This commit is contained in:
parent
a02f0570ae
commit
c1a0f5e3c0
2 changed files with 77 additions and 19 deletions
|
@ -14,6 +14,12 @@
|
||||||
#define LKC_DIRECT_LINK
|
#define LKC_DIRECT_LINK
|
||||||
#include "lkc.h"
|
#include "lkc.h"
|
||||||
|
|
||||||
|
static void conf_warning(const char *fmt, ...)
|
||||||
|
__attribute__ ((format (printf, 1, 2)));
|
||||||
|
|
||||||
|
static const char *conf_filename;
|
||||||
|
static int conf_lineno, conf_warnings, conf_unsaved;
|
||||||
|
|
||||||
const char conf_def_filename[] = ".config";
|
const char conf_def_filename[] = ".config";
|
||||||
|
|
||||||
const char conf_defname[] = "arch/$ARCH/defconfig";
|
const char conf_defname[] = "arch/$ARCH/defconfig";
|
||||||
|
@ -27,6 +33,17 @@ const char *conf_confnames[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void conf_warning(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
va_end(ap);
|
||||||
|
conf_warnings++;
|
||||||
|
}
|
||||||
|
|
||||||
static char *conf_expand_value(const char *in)
|
static char *conf_expand_value(const char *in)
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
@ -74,7 +91,6 @@ int conf_read_simple(const char *name)
|
||||||
FILE *in = NULL;
|
FILE *in = NULL;
|
||||||
char line[1024];
|
char line[1024];
|
||||||
char *p, *p2;
|
char *p, *p2;
|
||||||
int lineno = 0;
|
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -93,12 +109,18 @@ int conf_read_simple(const char *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in)
|
if (!in)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
conf_filename = name;
|
||||||
|
conf_lineno = 0;
|
||||||
|
conf_warnings = 0;
|
||||||
|
conf_unsaved = 0;
|
||||||
|
|
||||||
for_all_symbols(i, sym) {
|
for_all_symbols(i, sym) {
|
||||||
sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
|
sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
|
||||||
|
if (sym_is_choice(sym))
|
||||||
|
sym->flags &= ~SYMBOL_NEW;
|
||||||
sym->flags &= ~SYMBOL_VALID;
|
sym->flags &= ~SYMBOL_VALID;
|
||||||
switch (sym->type) {
|
switch (sym->type) {
|
||||||
case S_INT:
|
case S_INT:
|
||||||
|
@ -113,7 +135,7 @@ int conf_read_simple(const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), in)) {
|
while (fgets(line, sizeof(line), in)) {
|
||||||
lineno++;
|
conf_lineno++;
|
||||||
sym = NULL;
|
sym = NULL;
|
||||||
switch (line[0]) {
|
switch (line[0]) {
|
||||||
case '#':
|
case '#':
|
||||||
|
@ -127,7 +149,10 @@ int conf_read_simple(const char *name)
|
||||||
continue;
|
continue;
|
||||||
sym = sym_find(line + 9);
|
sym = sym_find(line + 9);
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9);
|
conf_warning("trying to assign nonexistent symbol %s", line + 9);
|
||||||
|
break;
|
||||||
|
} else if (!(sym->flags & SYMBOL_NEW)) {
|
||||||
|
conf_warning("trying to reassign symbol %s", sym->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (sym->type) {
|
switch (sym->type) {
|
||||||
|
@ -141,8 +166,10 @@ int conf_read_simple(const char *name)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
if (memcmp(line, "CONFIG_", 7))
|
if (memcmp(line, "CONFIG_", 7)) {
|
||||||
|
conf_warning("unexpected data");
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
p = strchr(line + 7, '=');
|
p = strchr(line + 7, '=');
|
||||||
if (!p)
|
if (!p)
|
||||||
continue;
|
continue;
|
||||||
|
@ -152,7 +179,10 @@ int conf_read_simple(const char *name)
|
||||||
*p2 = 0;
|
*p2 = 0;
|
||||||
sym = sym_find(line + 7);
|
sym = sym_find(line + 7);
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
|
conf_warning("trying to assign nonexistent symbol %s", line + 7);
|
||||||
|
break;
|
||||||
|
} else if (!(sym->flags & SYMBOL_NEW)) {
|
||||||
|
conf_warning("trying to reassign symbol %s", sym->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (sym->type) {
|
switch (sym->type) {
|
||||||
|
@ -173,6 +203,7 @@ int conf_read_simple(const char *name)
|
||||||
sym->flags &= ~SYMBOL_NEW;
|
sym->flags &= ~SYMBOL_NEW;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
conf_warning("symbol value '%s' invalid for %s", p, sym->name);
|
||||||
break;
|
break;
|
||||||
case S_STRING:
|
case S_STRING:
|
||||||
if (*p++ != '"')
|
if (*p++ != '"')
|
||||||
|
@ -185,8 +216,8 @@ int conf_read_simple(const char *name)
|
||||||
memmove(p2, p2 + 1, strlen(p2));
|
memmove(p2, p2 + 1, strlen(p2));
|
||||||
}
|
}
|
||||||
if (!p2) {
|
if (!p2) {
|
||||||
fprintf(stderr, "%s:%d: invalid string found\n", name, lineno);
|
conf_warning("invalid string found");
|
||||||
exit(1);
|
continue;
|
||||||
}
|
}
|
||||||
case S_INT:
|
case S_INT:
|
||||||
case S_HEX:
|
case S_HEX:
|
||||||
|
@ -194,8 +225,8 @@ int conf_read_simple(const char *name)
|
||||||
sym->user.val = strdup(p);
|
sym->user.val = strdup(p);
|
||||||
sym->flags &= ~SYMBOL_NEW;
|
sym->flags &= ~SYMBOL_NEW;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
|
conf_warning("symbol value '%s' invalid for %s", p, sym->name);
|
||||||
exit(1);
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -205,6 +236,7 @@ int conf_read_simple(const char *name)
|
||||||
case '\n':
|
case '\n':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
conf_warning("unexpected data");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (sym && sym_is_choice_value(sym)) {
|
if (sym && sym_is_choice_value(sym)) {
|
||||||
|
@ -213,17 +245,20 @@ int conf_read_simple(const char *name)
|
||||||
case no:
|
case no:
|
||||||
break;
|
break;
|
||||||
case mod:
|
case mod:
|
||||||
if (cs->user.tri == yes)
|
if (cs->user.tri == yes) {
|
||||||
/* warn? */;
|
conf_warning("%s creates inconsistent choice state", sym->name);
|
||||||
|
cs->flags |= SYMBOL_NEW;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case yes:
|
case yes:
|
||||||
if (cs->user.tri != no)
|
if (cs->user.tri != no) {
|
||||||
/* warn? */;
|
conf_warning("%s creates inconsistent choice state", sym->name);
|
||||||
|
cs->flags |= SYMBOL_NEW;
|
||||||
|
} else
|
||||||
cs->user.val = sym;
|
cs->user.val = sym;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
|
cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
|
||||||
cs->flags &= ~SYMBOL_NEW;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
@ -245,6 +280,28 @@ int conf_read(const char *name)
|
||||||
|
|
||||||
for_all_symbols(i, sym) {
|
for_all_symbols(i, sym) {
|
||||||
sym_calc_value(sym);
|
sym_calc_value(sym);
|
||||||
|
if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
|
||||||
|
goto sym_ok;
|
||||||
|
if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
|
||||||
|
/* check that calculated value agrees with saved value */
|
||||||
|
switch (sym->type) {
|
||||||
|
case S_BOOLEAN:
|
||||||
|
case S_TRISTATE:
|
||||||
|
if (sym->user.tri != sym_get_tristate_value(sym))
|
||||||
|
break;
|
||||||
|
if (!sym_is_choice(sym))
|
||||||
|
goto sym_ok;
|
||||||
|
default:
|
||||||
|
if (!strcmp(sym->curr.val, sym->user.val))
|
||||||
|
goto sym_ok;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
|
||||||
|
/* no previous value and not saved */
|
||||||
|
goto sym_ok;
|
||||||
|
conf_unsaved++;
|
||||||
|
/* maybe print value in verbose mode... */
|
||||||
|
sym_ok:
|
||||||
if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
|
if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
|
||||||
if (sym->visible == no)
|
if (sym->visible == no)
|
||||||
sym->flags |= SYMBOL_NEW;
|
sym->flags |= SYMBOL_NEW;
|
||||||
|
@ -252,8 +309,10 @@ int conf_read(const char *name)
|
||||||
case S_STRING:
|
case S_STRING:
|
||||||
case S_INT:
|
case S_INT:
|
||||||
case S_HEX:
|
case S_HEX:
|
||||||
if (!sym_string_within_range(sym, sym->user.val))
|
if (!sym_string_within_range(sym, sym->user.val)) {
|
||||||
sym->flags |= SYMBOL_NEW;
|
sym->flags |= SYMBOL_NEW;
|
||||||
|
sym->flags &= ~SYMBOL_VALID;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +325,7 @@ int conf_read(const char *name)
|
||||||
sym->flags |= e->right.sym->flags & SYMBOL_NEW;
|
sym->flags |= e->right.sym->flags & SYMBOL_NEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
sym_change_count = 1;
|
sym_change_count = conf_warnings && conf_unsaved;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,6 @@ char *zconf_curname(void);
|
||||||
|
|
||||||
/* confdata.c */
|
/* confdata.c */
|
||||||
extern const char conf_def_filename[];
|
extern const char conf_def_filename[];
|
||||||
extern char conf_filename[];
|
|
||||||
|
|
||||||
char *conf_get_default_confname(void);
|
char *conf_get_default_confname(void);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue