Commit f9f0d1c0 authored by Roman Zippel's avatar Roman Zippel Committed by Ben Collins

[PATCH] add more warnings

Add a number of warnings to avoid misuse of the previously added features
(most important check for recursive dependencies).
parent e4922a0b
......@@ -92,6 +92,9 @@ struct symbol {
#define SYMBOL_CHANGED 0x0400
#define SYMBOL_NEW 0x0800
#define SYMBOL_AUTO 0x1000
#define SYMBOL_CHECKED 0x2000
#define SYMBOL_CHECK_DONE 0x4000
#define SYMBOL_WARNED 0x8000
#define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 257
......
......@@ -94,7 +94,7 @@ void menu_set_type(int type)
sym->type = type;
return;
}
fprintf(stderr, "%s:%d: type of '%s' redefined from '%s' to '%s'\n",
fprintf(stderr, "%s:%d:warning: type of '%s' redefined from '%s' to '%s'\n",
current_entry->file->name, current_entry->lineno,
sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type));
}
......@@ -248,6 +248,47 @@ void menu_finalize(struct menu *parent)
}
}
if (sym && !(sym->flags & SYMBOL_WARNED)) {
struct symbol *sym2;
if (sym->type == S_UNKNOWN)
fprintf(stderr, "%s:%d:warning: config symbol defined without type\n",
parent->file->name, parent->lineno);
if (sym_is_choice(sym) && !parent->prompt)
fprintf(stderr, "%s:%d:warning: choice must have a prompt\n",
parent->file->name, parent->lineno);
for (prop = sym->prop; prop; prop = prop->next) {
switch (prop->type) {
case P_DEFAULT:
if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
prop->expr->type != E_SYMBOL)
fprintf(stderr, "%s:%d:warning: default must be a single symbol\n",
prop->file->name, prop->lineno);
break;
case P_SELECT:
sym2 = prop_get_symbol(prop);
if ((sym->type != S_BOOLEAN && sym->type != S_TRISTATE) ||
(sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE))
fprintf(stderr, "%s:%d:warning: enable is only allowed with boolean and tristate symbols\n",
prop->file->name, prop->lineno);
break;
case P_RANGE:
if (sym->type != S_INT && sym->type != S_HEX)
fprintf(stderr, "%s:%d:warning: range is only allowed for int or hex symbols\n",
prop->file->name, prop->lineno);
if (!sym_string_valid(sym, prop->expr->left.sym->name) ||
!sym_string_valid(sym, prop->expr->right.sym->name))
fprintf(stderr, "%s:%d:warning: range is invalid\n",
prop->file->name, prop->lineno);
break;
default:
;
}
}
sym->flags |= SYMBOL_WARNED;
}
if (sym && !sym_is_optional(sym) && parent->prompt) {
sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
expr_alloc_and(parent->prompt->visible.expr,
......
......@@ -651,6 +651,74 @@ struct symbol *sym_find(const char *name)
return symbol;
}
struct symbol *sym_check_deps(struct symbol *sym);
static struct symbol *sym_check_expr_deps(struct expr *e)
{
struct symbol *sym;
if (!e)
return NULL;
switch (e->type) {
case E_OR:
case E_AND:
sym = sym_check_expr_deps(e->left.expr);
if (sym)
return sym;
return sym_check_expr_deps(e->right.expr);
case E_NOT:
return sym_check_expr_deps(e->left.expr);
case E_EQUAL:
case E_UNEQUAL:
sym = sym_check_deps(e->left.sym);
if (sym)
return sym;
return sym_check_deps(e->right.sym);
case E_SYMBOL:
return sym_check_deps(e->left.sym);
default:
break;
}
printf("Oops! How to check %d?\n", e->type);
return NULL;
}
struct symbol *sym_check_deps(struct symbol *sym)
{
struct symbol *sym2;
struct property *prop;
if (sym->flags & SYMBOL_CHECK_DONE)
return NULL;
if (sym->flags & SYMBOL_CHECK) {
printf("Warning! Found recursive dependency: %s", sym->name);
return sym;
}
sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
sym2 = sym_check_expr_deps(sym->rev_dep.expr);
if (sym2)
goto out;
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->type == P_CHOICE)
continue;
sym2 = sym_check_expr_deps(prop->visible.expr);
if (sym2)
goto out;
if (prop->type != P_DEFAULT || sym_is_choice(sym))
continue;
sym2 = sym_check_expr_deps(prop->expr);
if (sym2)
goto out;
}
out:
if (sym2)
printf(" %s", sym->name);
sym->flags &= ~SYMBOL_CHECK;
return sym2;
}
struct property *prop_alloc(enum prop_type type, struct symbol *sym)
{
struct property *prop;
......
......@@ -1915,6 +1915,9 @@ yyreturn:
void conf_parse(const char *name)
{
struct symbol *sym;
int i;
zconf_initscan(name);
sym_init();
......@@ -1927,6 +1930,12 @@ void conf_parse(const char *name)
if (zconfnerrs)
exit(1);
menu_finalize(&rootmenu);
for_all_symbols(i, sym) {
if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
printf("\n");
else
sym->flags |= SYMBOL_CHECK_DONE;
}
sym_change_count = 1;
}
......
......@@ -477,6 +477,9 @@ symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
void conf_parse(const char *name)
{
struct symbol *sym;
int i;
zconf_initscan(name);
sym_init();
......@@ -489,6 +492,12 @@ void conf_parse(const char *name)
if (zconfnerrs)
exit(1);
menu_finalize(&rootmenu);
for_all_symbols(i, sym) {
if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
printf("\n");
else
sym->flags |= SYMBOL_CHECK_DONE;
}
sym_change_count = 1;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment