aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig/zconf.y
diff options
context:
space:
mode:
authorRoman Zippel <zippel@linux-m68k.org>2005-11-09 00:34:53 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:55:54 -0500
commita02f0570ae201c495ee991b959bb974af18f35cc (patch)
tree363e06307b7355caa2435a006c5385a1149bb7cc /scripts/kconfig/zconf.y
parent3370f9f0d9c7d14bf71aab27fa45c0537f130614 (diff)
[PATCH] kconfig: improve error handling in the parser
Add a few error tokens to the parser to catch common errors and print more descriptive error messages. 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>
Diffstat (limited to 'scripts/kconfig/zconf.y')
-rw-r--r--scripts/kconfig/zconf.y173
1 files changed, 100 insertions, 73 deletions
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 1211781675b8..1f61fba6aa28 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -25,21 +25,25 @@ int cdebug = PRINTD;
25 25
26extern int zconflex(void); 26extern int zconflex(void);
27static void zconfprint(const char *err, ...); 27static void zconfprint(const char *err, ...);
28static void zconf_error(const char *err, ...);
28static void zconferror(const char *err); 29static void zconferror(const char *err);
29static bool zconf_endtoken(int token, int starttoken, int endtoken); 30static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
30 31
31struct symbol *symbol_hash[257]; 32struct symbol *symbol_hash[257];
32 33
33static struct menu *current_menu, *current_entry; 34static struct menu *current_menu, *current_entry;
34 35
36#define YYDEBUG 0
37#if YYDEBUG
35#define YYERROR_VERBOSE 38#define YYERROR_VERBOSE
39#endif
36%} 40%}
37%expect 40 41%expect 26
38 42
39%union 43%union
40{ 44{
41 int token;
42 char *string; 45 char *string;
46 struct file *file;
43 struct symbol *symbol; 47 struct symbol *symbol;
44 struct expr *expr; 48 struct expr *expr;
45 struct menu *menu; 49 struct menu *menu;
@@ -74,7 +78,6 @@ static struct menu *current_menu, *current_entry;
74%token T_CLOSE_PAREN 78%token T_CLOSE_PAREN
75%token T_OPEN_PAREN 79%token T_OPEN_PAREN
76%token T_EOL 80%token T_EOL
77%token T_EOF
78 81
79%left T_OR 82%left T_OR
80%left T_AND 83%left T_AND
@@ -82,34 +85,54 @@ static struct menu *current_menu, *current_entry;
82%nonassoc T_NOT 85%nonassoc T_NOT
83 86
84%type <string> prompt 87%type <string> prompt
85%type <string> source
86%type <symbol> symbol 88%type <symbol> symbol
87%type <expr> expr 89%type <expr> expr
88%type <expr> if_expr 90%type <expr> if_expr
89%type <token> end 91%type <id> end
92%type <id> option_name
93%type <menu> if_entry menu_entry choice_entry
94
95%destructor {
96 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
97 $$->file->name, $$->lineno);
98 if (current_menu == $$)
99 menu_end_menu();
100} if_entry menu_entry choice_entry
90 101
91%% 102%%
92input: /* empty */ 103input: stmt_list;
93 | input block 104
105stmt_list:
106 /* empty */
107 | stmt_list common_stmt
108 | stmt_list choice_stmt
109 | stmt_list menu_stmt
110 | stmt_list T_MAINMENU prompt nl
111 | stmt_list end { zconf_error("unexpected end statement"); }
112 | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
113 | stmt_list option_name error T_EOL
114{
115 zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
116}
117 | stmt_list error T_EOL { zconf_error("invalid statement"); }
94; 118;
95 119
96block: common_block 120option_name:
97 | choice_stmt 121 T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
98 | menu_stmt
99 | T_MAINMENU prompt nl_or_eof
100 | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
101 | T_ENDIF { zconfprint("unexpected 'endif' statement"); }
102 | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
103 | error nl_or_eof { zconfprint("syntax error"); yyerrok; }
104; 122;
105 123
106common_block: 124common_stmt:
107 if_stmt 125 T_EOL
126 | if_stmt
108 | comment_stmt 127 | comment_stmt
109 | config_stmt 128 | config_stmt
110 | menuconfig_stmt 129 | menuconfig_stmt
111 | source_stmt 130 | source_stmt
112 | nl_or_eof 131;
132
133option_error:
134 T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); }
135 | error T_EOL { zconf_error("invalid option"); }
113; 136;
114 137
115 138
@@ -152,6 +175,7 @@ config_option_list:
152 | config_option_list config_option 175 | config_option_list config_option
153 | config_option_list depends 176 | config_option_list depends
154 | config_option_list help 177 | config_option_list help
178 | config_option_list option_error
155 | config_option_list T_EOL 179 | config_option_list T_EOL
156; 180;
157 181
@@ -204,8 +228,7 @@ choice: T_CHOICE T_EOL
204 228
205choice_entry: choice choice_option_list 229choice_entry: choice choice_option_list
206{ 230{
207 menu_end_entry(); 231 $$ = menu_add_menu();
208 menu_add_menu();
209}; 232};
210 233
211choice_end: end 234choice_end: end
@@ -216,13 +239,8 @@ choice_end: end
216 } 239 }
217}; 240};
218 241
219choice_stmt: 242choice_stmt: choice_entry choice_block choice_end
220 choice_entry choice_block choice_end 243;
221 | choice_entry choice_block
222{
223 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
224 zconfnerrs++;
225};
226 244
227choice_option_list: 245choice_option_list:
228 /* empty */ 246 /* empty */
@@ -230,6 +248,7 @@ choice_option_list:
230 | choice_option_list depends 248 | choice_option_list depends
231 | choice_option_list help 249 | choice_option_list help
232 | choice_option_list T_EOL 250 | choice_option_list T_EOL
251 | choice_option_list option_error
233; 252;
234 253
235choice_option: T_PROMPT prompt if_expr T_EOL 254choice_option: T_PROMPT prompt if_expr T_EOL
@@ -267,18 +286,17 @@ choice_option: T_DEFAULT T_WORD if_expr T_EOL
267 286
268choice_block: 287choice_block:
269 /* empty */ 288 /* empty */
270 | choice_block common_block 289 | choice_block common_stmt
271; 290;
272 291
273/* if entry */ 292/* if entry */
274 293
275if: T_IF expr T_EOL 294if_entry: T_IF expr nl
276{ 295{
277 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 296 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
278 menu_add_entry(NULL); 297 menu_add_entry(NULL);
279 menu_add_dep($2); 298 menu_add_dep($2);
280 menu_end_entry(); 299 $$ = menu_add_menu();
281 menu_add_menu();
282}; 300};
283 301
284if_end: end 302if_end: end
@@ -289,17 +307,12 @@ if_end: end
289 } 307 }
290}; 308};
291 309
292if_stmt: 310if_stmt: if_entry if_block if_end
293 if if_block if_end 311;
294 | if if_block
295{
296 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
297 zconfnerrs++;
298};
299 312
300if_block: 313if_block:
301 /* empty */ 314 /* empty */
302 | if_block common_block 315 | if_block common_stmt
303 | if_block menu_stmt 316 | if_block menu_stmt
304 | if_block choice_stmt 317 | if_block choice_stmt
305; 318;
@@ -315,8 +328,7 @@ menu: T_MENU prompt T_EOL
315 328
316menu_entry: menu depends_list 329menu_entry: menu depends_list
317{ 330{
318 menu_end_entry(); 331 $$ = menu_add_menu();
319 menu_add_menu();
320}; 332};
321 333
322menu_end: end 334menu_end: end
@@ -327,31 +339,20 @@ menu_end: end
327 } 339 }
328}; 340};
329 341
330menu_stmt: 342menu_stmt: menu_entry menu_block menu_end
331 menu_entry menu_block menu_end 343;
332 | menu_entry menu_block
333{
334 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
335 zconfnerrs++;
336};
337 344
338menu_block: 345menu_block:
339 /* empty */ 346 /* empty */
340 | menu_block common_block 347 | menu_block common_stmt
341 | menu_block menu_stmt 348 | menu_block menu_stmt
342 | menu_block choice_stmt 349 | menu_block choice_stmt
343 | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
344; 350;
345 351
346source: T_SOURCE prompt T_EOL 352source_stmt: T_SOURCE prompt T_EOL
347{ 353{
348 $$ = $2;
349 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); 354 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
350}; 355 zconf_nextfile($2);
351
352source_stmt: source
353{
354 zconf_nextfile($1);
355}; 356};
356 357
357/* comment entry */ 358/* comment entry */
@@ -383,9 +384,11 @@ help: help_start T_HELPTEXT
383 384
384/* depends option */ 385/* depends option */
385 386
386depends_list: /* empty */ 387depends_list:
387 | depends_list depends 388 /* empty */
388 | depends_list T_EOL 389 | depends_list depends
390 | depends_list T_EOL
391 | depends_list option_error
389; 392;
390 393
391depends: T_DEPENDS T_ON expr T_EOL 394depends: T_DEPENDS T_ON expr T_EOL
@@ -417,13 +420,15 @@ prompt: T_WORD
417 | T_WORD_QUOTE 420 | T_WORD_QUOTE
418; 421;
419 422
420end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; } 423end: T_ENDMENU T_EOL { $$ = $1; }
421 | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; } 424 | T_ENDCHOICE T_EOL { $$ = $1; }
422 | T_ENDIF nl_or_eof { $$ = T_ENDIF; } 425 | T_ENDIF T_EOL { $$ = $1; }
423; 426;
424 427
425nl_or_eof: 428nl:
426 T_EOL | T_EOF; 429 T_EOL
430 | nl T_EOL
431;
427 432
428if_expr: /* empty */ { $$ = NULL; } 433if_expr: /* empty */ { $$ = NULL; }
429 | T_IF expr { $$ = $2; } 434 | T_IF expr { $$ = $2; }
@@ -456,7 +461,10 @@ void conf_parse(const char *name)
456 modules_sym = sym_lookup("MODULES", 0); 461 modules_sym = sym_lookup("MODULES", 0);
457 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); 462 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
458 463
459 //zconfdebug = 1; 464#if YYDEBUG
465 if (getenv("ZCONF_DEBUG"))
466 zconfdebug = 1;
467#endif
460 zconfparse(); 468 zconfparse();
461 if (zconfnerrs) 469 if (zconfnerrs)
462 exit(1); 470 exit(1);
@@ -477,20 +485,25 @@ const char *zconf_tokenname(int token)
477 case T_ENDCHOICE: return "endchoice"; 485 case T_ENDCHOICE: return "endchoice";
478 case T_IF: return "if"; 486 case T_IF: return "if";
479 case T_ENDIF: return "endif"; 487 case T_ENDIF: return "endif";
488 case T_DEPENDS: return "depends";
480 } 489 }
481 return "<token>"; 490 return "<token>";
482} 491}
483 492
484static bool zconf_endtoken(int token, int starttoken, int endtoken) 493static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
485{ 494{
486 if (token != endtoken) { 495 if (id->token != endtoken) {
487 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); 496 zconf_error("unexpected '%s' within %s block",
497 kconf_id_strings + id->name, zconf_tokenname(starttoken));
488 zconfnerrs++; 498 zconfnerrs++;
489 return false; 499 return false;
490 } 500 }
491 if (current_menu->file != current_file) { 501 if (current_menu->file != current_file) {
492 zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); 502 zconf_error("'%s' in different file than '%s'",
493 zconfprint("location of the '%s'", zconf_tokenname(starttoken)); 503 kconf_id_strings + id->name, zconf_tokenname(starttoken));
504 fprintf(stderr, "%s:%d: location of the '%s'\n",
505 current_menu->file->name, current_menu->lineno,
506 zconf_tokenname(starttoken));
494 zconfnerrs++; 507 zconfnerrs++;
495 return false; 508 return false;
496 } 509 }
@@ -501,7 +514,19 @@ static void zconfprint(const char *err, ...)
501{ 514{
502 va_list ap; 515 va_list ap;
503 516
504 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); 517 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
518 va_start(ap, err);
519 vfprintf(stderr, err, ap);
520 va_end(ap);
521 fprintf(stderr, "\n");
522}
523
524static void zconf_error(const char *err, ...)
525{
526 va_list ap;
527
528 zconfnerrs++;
529 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
505 va_start(ap, err); 530 va_start(ap, err);
506 vfprintf(stderr, err, ap); 531 vfprintf(stderr, err, ap);
507 va_end(ap); 532 va_end(ap);
@@ -510,7 +535,9 @@ static void zconfprint(const char *err, ...)
510 535
511static void zconferror(const char *err) 536static void zconferror(const char *err)
512{ 537{
538#if YYDEBUG
513 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); 539 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
540#endif
514} 541}
515 542
516void print_quoted_string(FILE *out, const char *str) 543void print_quoted_string(FILE *out, const char *str)