aboutsummaryrefslogtreecommitdiff
path: root/scripts/config/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/config/menu.c')
-rw-r--r--scripts/config/menu.c126
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;
16struct file *file_list; 16struct file *file_list;
17struct file *current_file; 17struct file *current_file;
18 18
19static 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
29static 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
19void menu_init(void) 39void 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
102struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) 122struct 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
155void 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
136void menu_finalize(struct menu *parent) 199void 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