Commit a26fd06e authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Kconfig: use select statements

From: Sam Ravnborg <sam@ravnborg.org>

- Use keyword select in relevant warning

- Include more information in warnings related to select

- Move part of error-checking to a sepearate function

- Added helpers used when issuing warnings - makes code simpler

- Wrapped most edited lines at column 80
parent 50f33737
...@@ -16,6 +16,26 @@ static struct menu **last_entry_ptr; ...@@ -16,6 +16,26 @@ static struct menu **last_entry_ptr;
struct file *file_list; struct file *file_list;
struct file *current_file; struct file *current_file;
static void menu_warn(struct menu *menu, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
}
static void prop_warn(struct property *prop, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
}
void menu_init(void) void menu_init(void)
{ {
current_entry = current_menu = &rootmenu; current_entry = current_menu = &rootmenu;
...@@ -94,9 +114,9 @@ void menu_set_type(int type) ...@@ -94,9 +114,9 @@ void menu_set_type(int type)
sym->type = type; sym->type = type;
return; return;
} }
fprintf(stderr, "%s:%d:warning: type of '%s' redefined from '%s' to '%s'\n", menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n",
current_entry->file->name, current_entry->lineno, sym->name ? sym->name : "<choice>",
sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type)); sym_type_name(sym->type), sym_type_name(type));
} }
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
...@@ -110,8 +130,7 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e ...@@ -110,8 +130,7 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
if (prompt) { if (prompt) {
if (current_entry->prompt) if (current_entry->prompt)
fprintf(stderr, "%s:%d: prompt redefined\n", menu_warn(current_entry, "prompt redefined\n");
current_entry->file->name, current_entry->lineno);
current_entry->prompt = prop; current_entry->prompt = prop;
} }
...@@ -133,6 +152,50 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) ...@@ -133,6 +152,50 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
} }
void sym_check_prop(struct symbol *sym)
{
struct property *prop;
struct symbol *sym2;
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)
prop_warn(prop,
"default for config symbol '%'"
" must be a single symbol", sym->name);
break;
case P_SELECT:
sym2 = prop_get_symbol(prop);
if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
prop_warn(prop,
"config symbol '%s' uses select, but is "
"not boolean or tristate", sym->name);
else if (sym2->type == S_UNKNOWN)
prop_warn(prop,
"'select' used by config symbol '%s' "
"refer to undefined symbol '%s'",
sym->name, sym2->name);
else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)
prop_warn(prop,
"'%s' has wrong type. 'select' only "
"accept arguments of boolean and "
"tristate type", sym2->name);
break;
case P_RANGE:
if (sym->type != S_INT && sym->type != S_HEX)
prop_warn(prop, "range is only allowed "
"for int or hex symbols");
if (!sym_string_valid(sym, prop->expr->left.sym->name) ||
!sym_string_valid(sym, prop->expr->right.sym->name))
prop_warn(prop, "range is invalid");
break;
default:
;
}
}
}
void menu_finalize(struct menu *parent) void menu_finalize(struct menu *parent)
{ {
struct menu *menu, *last_menu; struct menu *menu, *last_menu;
...@@ -222,17 +285,16 @@ void menu_finalize(struct menu *parent) ...@@ -222,17 +285,16 @@ void menu_finalize(struct menu *parent)
if (sym && sym_is_choice(sym) && menu->sym) { if (sym && sym_is_choice(sym) && menu->sym) {
menu->sym->flags |= SYMBOL_CHOICEVAL; menu->sym->flags |= SYMBOL_CHOICEVAL;
if (!menu->prompt) if (!menu->prompt)
fprintf(stderr, "%s:%d:warning: choice value must have a prompt\n", menu_warn(menu, "choice value must have a prompt");
menu->file->name, menu->lineno);
for (prop = menu->sym->prop; prop; prop = prop->next) { for (prop = menu->sym->prop; prop; prop = prop->next) {
if (prop->type == P_PROMPT && prop->menu != menu) { if (prop->type == P_PROMPT && prop->menu != menu) {
fprintf(stderr, "%s:%d:warning: choice values currently only support a single prompt\n", prop_warn(prop, "choice values "
prop->file->name, prop->lineno); "currently only support a "
"single prompt");
} }
if (prop->type == P_DEFAULT) if (prop->type == P_DEFAULT)
fprintf(stderr, "%s:%d:warning: defaults for choice values not supported\n", prop_warn(prop, "defaults for choice "
prop->file->name, prop->lineno); "values not supported");
} }
current_entry = menu; current_entry = menu;
menu_set_type(sym->type); menu_set_type(sym->type);
...@@ -256,43 +318,15 @@ void menu_finalize(struct menu *parent) ...@@ -256,43 +318,15 @@ void menu_finalize(struct menu *parent)
} }
if (sym && !(sym->flags & SYMBOL_WARNED)) { if (sym && !(sym->flags & SYMBOL_WARNED)) {
struct symbol *sym2;
if (sym->type == S_UNKNOWN) if (sym->type == S_UNKNOWN)
fprintf(stderr, "%s:%d:warning: config symbol defined without type\n", menu_warn(parent, "config symbol defined "
parent->file->name, parent->lineno); "without type\n");
if (sym_is_choice(sym) && !parent->prompt) if (sym_is_choice(sym) && !parent->prompt)
fprintf(stderr, "%s:%d:warning: choice must have a prompt\n", menu_warn(parent, "choice must have a prompt\n");
parent->file->name, parent->lineno);
/* Check properties connected to this symbol */
for (prop = sym->prop; prop; prop = prop->next) { sym_check_prop(sym);
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; sym->flags |= SYMBOL_WARNED;
} }
......
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