diff options
Diffstat (limited to 'scripts/config/menu.c')
-rw-r--r-- | scripts/config/menu.c | 126 |
1 files changed, 80 insertions, 46 deletions
diff --git a/scripts/config/menu.c b/scripts/config/menu.c index 9b8d389e6..6425296fc 100644 --- a/scripts/config/menu.c +++ b/scripts/config/menu.c | |||
@@ -16,6 +16,26 @@ static struct menu **last_entry_ptr; | |||
16 | struct file *file_list; | 16 | struct file *file_list; |
17 | struct file *current_file; | 17 | struct file *current_file; |
18 | 18 | ||
19 | static void menu_warn(struct menu *menu, const char *fmt, ...) | ||
20 | { | ||
21 | va_list ap; | ||
22 | va_start(ap, fmt); | ||
23 | fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno); | ||
24 | vfprintf(stderr, fmt, ap); | ||
25 | fprintf(stderr, "\n"); | ||
26 | va_end(ap); | ||
27 | } | ||
28 | |||
29 | static void prop_warn(struct property *prop, const char *fmt, ...) | ||
30 | { | ||
31 | va_list ap; | ||
32 | va_start(ap, fmt); | ||
33 | fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno); | ||
34 | vfprintf(stderr, fmt, ap); | ||
35 | fprintf(stderr, "\n"); | ||
36 | va_end(ap); | ||
37 | } | ||
38 | |||
19 | void menu_init(void) | 39 | void menu_init(void) |
20 | { | 40 | { |
21 | current_entry = current_menu = &rootmenu; | 41 | current_entry = current_menu = &rootmenu; |
@@ -94,9 +114,9 @@ void menu_set_type(int type) | |||
94 | sym->type = type; | 114 | sym->type = type; |
95 | return; | 115 | return; |
96 | } | 116 | } |
97 | fprintf(stderr, "%s:%d:warning: type of '%s' redefined from '%s' to '%s'\n", | 117 | menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n", |
98 | current_entry->file->name, current_entry->lineno, | 118 | sym->name ? sym->name : "<choice>", |
99 | sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type)); | 119 | sym_type_name(sym->type), sym_type_name(type)); |
100 | } | 120 | } |
101 | 121 | ||
102 | struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) | 122 | 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 | 130 | ||
111 | if (prompt) { | 131 | if (prompt) { |
112 | if (current_entry->prompt) | 132 | if (current_entry->prompt) |
113 | fprintf(stderr, "%s:%d: prompt redefined\n", | 133 | menu_warn(current_entry, "prompt redefined\n"); |
114 | current_entry->file->name, current_entry->lineno); | ||
115 | current_entry->prompt = prop; | 134 | current_entry->prompt = prop; |
116 | } | 135 | } |
117 | 136 | ||
@@ -133,6 +152,50 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) | |||
133 | menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); | 152 | menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); |
134 | } | 153 | } |
135 | 154 | ||
155 | void sym_check_prop(struct symbol *sym) | ||
156 | { | ||
157 | struct property *prop; | ||
158 | struct symbol *sym2; | ||
159 | for (prop = sym->prop; prop; prop = prop->next) { | ||
160 | switch (prop->type) { | ||
161 | case P_DEFAULT: | ||
162 | if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && | ||
163 | prop->expr->type != E_SYMBOL) | ||
164 | prop_warn(prop, | ||
165 | "default for config symbol '%'" | ||
166 | " must be a single symbol", sym->name); | ||
167 | break; | ||
168 | case P_SELECT: | ||
169 | sym2 = prop_get_symbol(prop); | ||
170 | if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) | ||
171 | prop_warn(prop, | ||
172 | "config symbol '%s' uses select, but is " | ||
173 | "not boolean or tristate", sym->name); | ||
174 | else if (sym2->type == S_UNKNOWN) | ||
175 | prop_warn(prop, | ||
176 | "'select' used by config symbol '%s' " | ||
177 | "refer to undefined symbol '%s'", | ||
178 | sym->name, sym2->name); | ||
179 | else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE) | ||
180 | prop_warn(prop, | ||
181 | "'%s' has wrong type. 'select' only " | ||
182 | "accept arguments of boolean and " | ||
183 | "tristate type", sym2->name); | ||
184 | break; | ||
185 | case P_RANGE: | ||
186 | if (sym->type != S_INT && sym->type != S_HEX) | ||
187 | prop_warn(prop, "range is only allowed " | ||
188 | "for int or hex symbols"); | ||
189 | if (!sym_string_valid(sym, prop->expr->left.sym->name) || | ||
190 | !sym_string_valid(sym, prop->expr->right.sym->name)) | ||
191 | prop_warn(prop, "range is invalid"); | ||
192 | break; | ||
193 | default: | ||
194 | ; | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | |||
136 | void menu_finalize(struct menu *parent) | 199 | void menu_finalize(struct menu *parent) |
137 | { | 200 | { |
138 | struct menu *menu, *last_menu; | 201 | struct menu *menu, *last_menu; |
@@ -222,17 +285,16 @@ void menu_finalize(struct menu *parent) | |||
222 | if (sym && sym_is_choice(sym) && menu->sym) { | 285 | if (sym && sym_is_choice(sym) && menu->sym) { |
223 | menu->sym->flags |= SYMBOL_CHOICEVAL; | 286 | menu->sym->flags |= SYMBOL_CHOICEVAL; |
224 | if (!menu->prompt) | 287 | if (!menu->prompt) |
225 | fprintf(stderr, "%s:%d:warning: choice value must have a prompt\n", | 288 | menu_warn(menu, "choice value must have a prompt"); |
226 | menu->file->name, menu->lineno); | ||
227 | for (prop = menu->sym->prop; prop; prop = prop->next) { | 289 | for (prop = menu->sym->prop; prop; prop = prop->next) { |
228 | if (prop->type == P_PROMPT && prop->menu != menu) { | 290 | if (prop->type == P_PROMPT && prop->menu != menu) { |
229 | fprintf(stderr, "%s:%d:warning: choice values currently only support a single prompt\n", | 291 | prop_warn(prop, "choice values " |
230 | prop->file->name, prop->lineno); | 292 | "currently only support a " |
231 | 293 | "single prompt"); | |
232 | } | 294 | } |
233 | if (prop->type == P_DEFAULT) | 295 | if (prop->type == P_DEFAULT) |
234 | fprintf(stderr, "%s:%d:warning: defaults for choice values not supported\n", | 296 | prop_warn(prop, "defaults for choice " |
235 | prop->file->name, prop->lineno); | 297 | "values not supported"); |
236 | } | 298 | } |
237 | current_entry = menu; | 299 | current_entry = menu; |
238 | menu_set_type(sym->type); | 300 | menu_set_type(sym->type); |
@@ -256,43 +318,15 @@ void menu_finalize(struct menu *parent) | |||
256 | } | 318 | } |
257 | 319 | ||
258 | if (sym && !(sym->flags & SYMBOL_WARNED)) { | 320 | if (sym && !(sym->flags & SYMBOL_WARNED)) { |
259 | struct symbol *sym2; | ||
260 | if (sym->type == S_UNKNOWN) | 321 | if (sym->type == S_UNKNOWN) |
261 | fprintf(stderr, "%s:%d:warning: config symbol defined without type\n", | 322 | menu_warn(parent, "config symbol defined " |
262 | parent->file->name, parent->lineno); | 323 | "without type\n"); |
263 | 324 | ||
264 | if (sym_is_choice(sym) && !parent->prompt) | 325 | if (sym_is_choice(sym) && !parent->prompt) |
265 | fprintf(stderr, "%s:%d:warning: choice must have a prompt\n", | 326 | menu_warn(parent, "choice must have a prompt\n"); |
266 | parent->file->name, parent->lineno); | 327 | |
267 | 328 | /* Check properties connected to this symbol */ | |
268 | for (prop = sym->prop; prop; prop = prop->next) { | 329 | sym_check_prop(sym); |
269 | switch (prop->type) { | ||
270 | case P_DEFAULT: | ||
271 | if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && | ||
272 | prop->expr->type != E_SYMBOL) | ||
273 | fprintf(stderr, "%s:%d:warning: default must be a single symbol\n", | ||
274 | prop->file->name, prop->lineno); | ||
275 | break; | ||
276 | case P_SELECT: | ||
277 | sym2 = prop_get_symbol(prop); | ||
278 | if ((sym->type != S_BOOLEAN && sym->type != S_TRISTATE) || | ||
279 | (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)) | ||
280 | fprintf(stderr, "%s:%d:warning: enable is only allowed with boolean and tristate symbols\n", | ||
281 | prop->file->name, prop->lineno); | ||
282 | break; | ||
283 | case P_RANGE: | ||
284 | if (sym->type != S_INT && sym->type != S_HEX) | ||
285 | fprintf(stderr, "%s:%d:warning: range is only allowed for int or hex symbols\n", | ||
286 | prop->file->name, prop->lineno); | ||
287 | if (!sym_string_valid(sym, prop->expr->left.sym->name) || | ||
288 | !sym_string_valid(sym, prop->expr->right.sym->name)) | ||
289 | fprintf(stderr, "%s:%d:warning: range is invalid\n", | ||
290 | prop->file->name, prop->lineno); | ||
291 | break; | ||
292 | default: | ||
293 | ; | ||
294 | } | ||
295 | } | ||
296 | sym->flags |= SYMBOL_WARNED; | 330 | sym->flags |= SYMBOL_WARNED; |
297 | } | 331 | } |
298 | 332 | ||