Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


imported SEABIOS source tree
[palacios.git] / bios / seabios / tools / kconfig / zconf.y
1 %{
2 /*
3  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4  * Released under the terms of the GNU GPL v2.0.
5  */
6
7 #include <ctype.h>
8 #include <stdarg.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdbool.h>
13
14 #define LKC_DIRECT_LINK
15 #include "lkc.h"
16
17 #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
18
19 #define PRINTD          0x0001
20 #define DEBUG_PARSE     0x0002
21
22 int cdebug = PRINTD;
23
24 extern int zconflex(void);
25 static void zconfprint(const char *err, ...);
26 static void zconf_error(const char *err, ...);
27 static void zconferror(const char *err);
28 static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
29
30 struct symbol *symbol_hash[SYMBOL_HASHSIZE];
31
32 static struct menu *current_menu, *current_entry;
33
34 #define YYDEBUG 0
35 #if YYDEBUG
36 #define YYERROR_VERBOSE
37 #endif
38 %}
39 %expect 30
40
41 %union
42 {
43         char *string;
44         struct file *file;
45         struct symbol *symbol;
46         struct expr *expr;
47         struct menu *menu;
48         struct kconf_id *id;
49 }
50
51 %token <id>T_MAINMENU
52 %token <id>T_MENU
53 %token <id>T_ENDMENU
54 %token <id>T_SOURCE
55 %token <id>T_CHOICE
56 %token <id>T_ENDCHOICE
57 %token <id>T_COMMENT
58 %token <id>T_CONFIG
59 %token <id>T_MENUCONFIG
60 %token <id>T_HELP
61 %token <string> T_HELPTEXT
62 %token <id>T_IF
63 %token <id>T_ENDIF
64 %token <id>T_DEPENDS
65 %token <id>T_OPTIONAL
66 %token <id>T_PROMPT
67 %token <id>T_TYPE
68 %token <id>T_DEFAULT
69 %token <id>T_SELECT
70 %token <id>T_RANGE
71 %token <id>T_VISIBLE
72 %token <id>T_OPTION
73 %token <id>T_ON
74 %token <string> T_WORD
75 %token <string> T_WORD_QUOTE
76 %token T_UNEQUAL
77 %token T_CLOSE_PAREN
78 %token T_OPEN_PAREN
79 %token T_EOL
80
81 %left T_OR
82 %left T_AND
83 %left T_EQUAL T_UNEQUAL
84 %nonassoc T_NOT
85
86 %type <string> prompt
87 %type <symbol> symbol
88 %type <expr> expr
89 %type <expr> if_expr
90 %type <id> end
91 %type <id> option_name
92 %type <menu> if_entry menu_entry choice_entry
93 %type <string> symbol_option_arg word_opt
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
101
102 %{
103 /* Include zconf.hash.c here so it can see the token constants. */
104 #include "zconf.hash.c"
105 %}
106
107 %%
108 input: nl start | start;
109
110 start: mainmenu_stmt stmt_list | stmt_list;
111
112 stmt_list:
113           /* empty */
114         | stmt_list common_stmt
115         | stmt_list choice_stmt
116         | stmt_list menu_stmt
117         | stmt_list end                 { zconf_error("unexpected end statement"); }
118         | stmt_list T_WORD error T_EOL  { zconf_error("unknown statement \"%s\"", $2); }
119         | stmt_list option_name error T_EOL
120 {
121         zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
122 }
123         | stmt_list error T_EOL         { zconf_error("invalid statement"); }
124 ;
125
126 option_name:
127         T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
128 ;
129
130 common_stmt:
131           T_EOL
132         | if_stmt
133         | comment_stmt
134         | config_stmt
135         | menuconfig_stmt
136         | source_stmt
137 ;
138
139 option_error:
140           T_WORD error T_EOL            { zconf_error("unknown option \"%s\"", $1); }
141         | error T_EOL                   { zconf_error("invalid option"); }
142 ;
143
144
145 /* config/menuconfig entry */
146
147 config_entry_start: T_CONFIG T_WORD T_EOL
148 {
149         struct symbol *sym = sym_lookup($2, 0);
150         sym->flags |= SYMBOL_OPTIONAL;
151         menu_add_entry(sym);
152         printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
153 };
154
155 config_stmt: config_entry_start config_option_list
156 {
157         menu_end_entry();
158         printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
159 };
160
161 menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
162 {
163         struct symbol *sym = sym_lookup($2, 0);
164         sym->flags |= SYMBOL_OPTIONAL;
165         menu_add_entry(sym);
166         printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
167 };
168
169 menuconfig_stmt: menuconfig_entry_start config_option_list
170 {
171         if (current_entry->prompt)
172                 current_entry->prompt->type = P_MENU;
173         else
174                 zconfprint("warning: menuconfig statement without prompt");
175         menu_end_entry();
176         printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
177 };
178
179 config_option_list:
180           /* empty */
181         | config_option_list config_option
182         | config_option_list symbol_option
183         | config_option_list depends
184         | config_option_list help
185         | config_option_list option_error
186         | config_option_list T_EOL
187 ;
188
189 config_option: T_TYPE prompt_stmt_opt T_EOL
190 {
191         menu_set_type($1->stype);
192         printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
193                 zconf_curname(), zconf_lineno(),
194                 $1->stype);
195 };
196
197 config_option: T_PROMPT prompt if_expr T_EOL
198 {
199         menu_add_prompt(P_PROMPT, $2, $3);
200         printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
201 };
202
203 config_option: T_DEFAULT expr if_expr T_EOL
204 {
205         menu_add_expr(P_DEFAULT, $2, $3);
206         if ($1->stype != S_UNKNOWN)
207                 menu_set_type($1->stype);
208         printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
209                 zconf_curname(), zconf_lineno(),
210                 $1->stype);
211 };
212
213 config_option: T_SELECT T_WORD if_expr T_EOL
214 {
215         menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
216         printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
217 };
218
219 config_option: T_RANGE symbol symbol if_expr T_EOL
220 {
221         menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
222         printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
223 };
224
225 symbol_option: T_OPTION symbol_option_list T_EOL
226 ;
227
228 symbol_option_list:
229           /* empty */
230         | symbol_option_list T_WORD symbol_option_arg
231 {
232         struct kconf_id *id = kconf_id_lookup($2, strlen($2));
233         if (id && id->flags & TF_OPTION)
234                 menu_add_option(id->token, $3);
235         else
236                 zconfprint("warning: ignoring unknown option %s", $2);
237         free($2);
238 };
239
240 symbol_option_arg:
241           /* empty */           { $$ = NULL; }
242         | T_EQUAL prompt        { $$ = $2; }
243 ;
244
245 /* choice entry */
246
247 choice: T_CHOICE word_opt T_EOL
248 {
249         struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE);
250         sym->flags |= SYMBOL_AUTO;
251         menu_add_entry(sym);
252         menu_add_expr(P_CHOICE, NULL, NULL);
253         printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
254 };
255
256 choice_entry: choice choice_option_list
257 {
258         $$ = menu_add_menu();
259 };
260
261 choice_end: end
262 {
263         if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
264                 menu_end_menu();
265                 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
266         }
267 };
268
269 choice_stmt: choice_entry choice_block choice_end
270 ;
271
272 choice_option_list:
273           /* empty */
274         | choice_option_list choice_option
275         | choice_option_list depends
276         | choice_option_list help
277         | choice_option_list T_EOL
278         | choice_option_list option_error
279 ;
280
281 choice_option: T_PROMPT prompt if_expr T_EOL
282 {
283         menu_add_prompt(P_PROMPT, $2, $3);
284         printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
285 };
286
287 choice_option: T_TYPE prompt_stmt_opt T_EOL
288 {
289         if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) {
290                 menu_set_type($1->stype);
291                 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
292                         zconf_curname(), zconf_lineno(),
293                         $1->stype);
294         } else
295                 YYERROR;
296 };
297
298 choice_option: T_OPTIONAL T_EOL
299 {
300         current_entry->sym->flags |= SYMBOL_OPTIONAL;
301         printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
302 };
303
304 choice_option: T_DEFAULT T_WORD if_expr T_EOL
305 {
306         if ($1->stype == S_UNKNOWN) {
307                 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
308                 printd(DEBUG_PARSE, "%s:%d:default\n",
309                         zconf_curname(), zconf_lineno());
310         } else
311                 YYERROR;
312 };
313
314 choice_block:
315           /* empty */
316         | choice_block common_stmt
317 ;
318
319 /* if entry */
320
321 if_entry: T_IF expr nl
322 {
323         printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
324         menu_add_entry(NULL);
325         menu_add_dep($2);
326         $$ = menu_add_menu();
327 };
328
329 if_end: end
330 {
331         if (zconf_endtoken($1, T_IF, T_ENDIF)) {
332                 menu_end_menu();
333                 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
334         }
335 };
336
337 if_stmt: if_entry if_block if_end
338 ;
339
340 if_block:
341           /* empty */
342         | if_block common_stmt
343         | if_block menu_stmt
344         | if_block choice_stmt
345 ;
346
347 /* mainmenu entry */
348
349 mainmenu_stmt: T_MAINMENU prompt nl
350 {
351         menu_add_prompt(P_MENU, $2, NULL);
352 };
353
354 /* menu entry */
355
356 menu: T_MENU prompt T_EOL
357 {
358         menu_add_entry(NULL);
359         menu_add_prompt(P_MENU, $2, NULL);
360         printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
361 };
362
363 menu_entry: menu visibility_list depends_list
364 {
365         $$ = menu_add_menu();
366 };
367
368 menu_end: end
369 {
370         if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
371                 menu_end_menu();
372                 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
373         }
374 };
375
376 menu_stmt: menu_entry menu_block menu_end
377 ;
378
379 menu_block:
380           /* empty */
381         | menu_block common_stmt
382         | menu_block menu_stmt
383         | menu_block choice_stmt
384 ;
385
386 source_stmt: T_SOURCE prompt T_EOL
387 {
388         printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
389         zconf_nextfile($2);
390 };
391
392 /* comment entry */
393
394 comment: T_COMMENT prompt T_EOL
395 {
396         menu_add_entry(NULL);
397         menu_add_prompt(P_COMMENT, $2, NULL);
398         printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
399 };
400
401 comment_stmt: comment depends_list
402 {
403         menu_end_entry();
404 };
405
406 /* help option */
407
408 help_start: T_HELP T_EOL
409 {
410         printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
411         zconf_starthelp();
412 };
413
414 help: help_start T_HELPTEXT
415 {
416         current_entry->help = $2;
417 };
418
419 /* depends option */
420
421 depends_list:
422           /* empty */
423         | depends_list depends
424         | depends_list T_EOL
425         | depends_list option_error
426 ;
427
428 depends: T_DEPENDS T_ON expr T_EOL
429 {
430         menu_add_dep($3);
431         printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
432 };
433
434 /* visibility option */
435
436 visibility_list:
437           /* empty */
438         | visibility_list visible
439         | visibility_list T_EOL
440 ;
441
442 visible: T_VISIBLE if_expr
443 {
444         menu_add_visibility($2);
445 };
446
447 /* prompt statement */
448
449 prompt_stmt_opt:
450           /* empty */
451         | prompt if_expr
452 {
453         menu_add_prompt(P_PROMPT, $1, $2);
454 };
455
456 prompt:   T_WORD
457         | T_WORD_QUOTE
458 ;
459
460 end:      T_ENDMENU T_EOL       { $$ = $1; }
461         | T_ENDCHOICE T_EOL     { $$ = $1; }
462         | T_ENDIF T_EOL         { $$ = $1; }
463 ;
464
465 nl:
466           T_EOL
467         | nl T_EOL
468 ;
469
470 if_expr:  /* empty */                   { $$ = NULL; }
471         | T_IF expr                     { $$ = $2; }
472 ;
473
474 expr:     symbol                                { $$ = expr_alloc_symbol($1); }
475         | symbol T_EQUAL symbol                 { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
476         | symbol T_UNEQUAL symbol               { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
477         | T_OPEN_PAREN expr T_CLOSE_PAREN       { $$ = $2; }
478         | T_NOT expr                            { $$ = expr_alloc_one(E_NOT, $2); }
479         | expr T_OR expr                        { $$ = expr_alloc_two(E_OR, $1, $3); }
480         | expr T_AND expr                       { $$ = expr_alloc_two(E_AND, $1, $3); }
481 ;
482
483 symbol:   T_WORD        { $$ = sym_lookup($1, 0); free($1); }
484         | T_WORD_QUOTE  { $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
485 ;
486
487 word_opt: /* empty */                   { $$ = NULL; }
488         | T_WORD
489
490 %%
491
492 void conf_parse(const char *name)
493 {
494         struct symbol *sym;
495         int i;
496
497         zconf_initscan(name);
498
499         sym_init();
500         _menu_init();
501         modules_sym = sym_lookup(NULL, 0);
502         modules_sym->type = S_BOOLEAN;
503         modules_sym->flags |= SYMBOL_AUTO;
504         rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
505
506 #if YYDEBUG
507         if (getenv("ZCONF_DEBUG"))
508                 zconfdebug = 1;
509 #endif
510         zconfparse();
511         if (zconfnerrs)
512                 exit(1);
513         if (!modules_sym->prop) {
514                 struct property *prop;
515
516                 prop = prop_alloc(P_DEFAULT, modules_sym);
517                 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
518         }
519
520         rootmenu.prompt->text = _(rootmenu.prompt->text);
521         rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
522
523         menu_finalize(&rootmenu);
524         for_all_symbols(i, sym) {
525                 if (sym_check_deps(sym))
526                         zconfnerrs++;
527         }
528         if (zconfnerrs)
529                 exit(1);
530         sym_set_change_count(1);
531 }
532
533 static const char *zconf_tokenname(int token)
534 {
535         switch (token) {
536         case T_MENU:            return "menu";
537         case T_ENDMENU:         return "endmenu";
538         case T_CHOICE:          return "choice";
539         case T_ENDCHOICE:       return "endchoice";
540         case T_IF:              return "if";
541         case T_ENDIF:           return "endif";
542         case T_DEPENDS:         return "depends";
543         case T_VISIBLE:         return "visible";
544         }
545         return "<token>";
546 }
547
548 static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
549 {
550         if (id->token != endtoken) {
551                 zconf_error("unexpected '%s' within %s block",
552                         kconf_id_strings + id->name, zconf_tokenname(starttoken));
553                 zconfnerrs++;
554                 return false;
555         }
556         if (current_menu->file != current_file) {
557                 zconf_error("'%s' in different file than '%s'",
558                         kconf_id_strings + id->name, zconf_tokenname(starttoken));
559                 fprintf(stderr, "%s:%d: location of the '%s'\n",
560                         current_menu->file->name, current_menu->lineno,
561                         zconf_tokenname(starttoken));
562                 zconfnerrs++;
563                 return false;
564         }
565         return true;
566 }
567
568 static void zconfprint(const char *err, ...)
569 {
570         va_list ap;
571
572         fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
573         va_start(ap, err);
574         vfprintf(stderr, err, ap);
575         va_end(ap);
576         fprintf(stderr, "\n");
577 }
578
579 static void zconf_error(const char *err, ...)
580 {
581         va_list ap;
582
583         zconfnerrs++;
584         fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
585         va_start(ap, err);
586         vfprintf(stderr, err, ap);
587         va_end(ap);
588         fprintf(stderr, "\n");
589 }
590
591 static void zconferror(const char *err)
592 {
593 #if YYDEBUG
594         fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
595 #endif
596 }
597
598 static void print_quoted_string(FILE *out, const char *str)
599 {
600         const char *p;
601         int len;
602
603         putc('"', out);
604         while ((p = strchr(str, '"'))) {
605                 len = p - str;
606                 if (len)
607                         fprintf(out, "%.*s", len, str);
608                 fputs("\\\"", out);
609                 str = p + 1;
610         }
611         fputs(str, out);
612         putc('"', out);
613 }
614
615 static void print_symbol(FILE *out, struct menu *menu)
616 {
617         struct symbol *sym = menu->sym;
618         struct property *prop;
619
620         if (sym_is_choice(sym))
621                 fprintf(out, "\nchoice\n");
622         else
623                 fprintf(out, "\nconfig %s\n", sym->name);
624         switch (sym->type) {
625         case S_BOOLEAN:
626                 fputs("  boolean\n", out);
627                 break;
628         case S_TRISTATE:
629                 fputs("  tristate\n", out);
630                 break;
631         case S_STRING:
632                 fputs("  string\n", out);
633                 break;
634         case S_INT:
635                 fputs("  integer\n", out);
636                 break;
637         case S_HEX:
638                 fputs("  hex\n", out);
639                 break;
640         default:
641                 fputs("  ???\n", out);
642                 break;
643         }
644         for (prop = sym->prop; prop; prop = prop->next) {
645                 if (prop->menu != menu)
646                         continue;
647                 switch (prop->type) {
648                 case P_PROMPT:
649                         fputs("  prompt ", out);
650                         print_quoted_string(out, prop->text);
651                         if (!expr_is_yes(prop->visible.expr)) {
652                                 fputs(" if ", out);
653                                 expr_fprint(prop->visible.expr, out);
654                         }
655                         fputc('\n', out);
656                         break;
657                 case P_DEFAULT:
658                         fputs( "  default ", out);
659                         expr_fprint(prop->expr, out);
660                         if (!expr_is_yes(prop->visible.expr)) {
661                                 fputs(" if ", out);
662                                 expr_fprint(prop->visible.expr, out);
663                         }
664                         fputc('\n', out);
665                         break;
666                 case P_CHOICE:
667                         fputs("  #choice value\n", out);
668                         break;
669                 case P_SELECT:
670                         fputs( "  select ", out);
671                         expr_fprint(prop->expr, out);
672                         fputc('\n', out);
673                         break;
674                 case P_RANGE:
675                         fputs( "  range ", out);
676                         expr_fprint(prop->expr, out);
677                         fputc('\n', out);
678                         break;
679                 case P_MENU:
680                         fputs( "  menu ", out);
681                         print_quoted_string(out, prop->text);
682                         fputc('\n', out);
683                         break;
684                 default:
685                         fprintf(out, "  unknown prop %d!\n", prop->type);
686                         break;
687                 }
688         }
689         if (menu->help) {
690                 int len = strlen(menu->help);
691                 while (menu->help[--len] == '\n')
692                         menu->help[len] = 0;
693                 fprintf(out, "  help\n%s\n", menu->help);
694         }
695 }
696
697 void zconfdump(FILE *out)
698 {
699         struct property *prop;
700         struct symbol *sym;
701         struct menu *menu;
702
703         menu = rootmenu.list;
704         while (menu) {
705                 if ((sym = menu->sym))
706                         print_symbol(out, menu);
707                 else if ((prop = menu->prompt)) {
708                         switch (prop->type) {
709                         case P_COMMENT:
710                                 fputs("\ncomment ", out);
711                                 print_quoted_string(out, prop->text);
712                                 fputs("\n", out);
713                                 break;
714                         case P_MENU:
715                                 fputs("\nmenu ", out);
716                                 print_quoted_string(out, prop->text);
717                                 fputs("\n", out);
718                                 break;
719                         default:
720                                 ;
721                         }
722                         if (!expr_is_yes(prop->visible.expr)) {
723                                 fputs("  depends ", out);
724                                 expr_fprint(prop->visible.expr, out);
725                                 fputc('\n', out);
726                         }
727                 }
728
729                 if (menu->list)
730                         menu = menu->list;
731                 else if (menu->next)
732                         menu = menu->next;
733                 else while ((menu = menu->parent)) {
734                         if (menu->prompt && menu->prompt->type == P_MENU)
735                                 fputs("\nendmenu\n", out);
736                         if (menu->next) {
737                                 menu = menu->next;
738                                 break;
739                         }
740                 }
741         }
742 }
743
744 #include "lex.zconf.c"
745 #include "util.c"
746 #include "confdata.c"
747 #include "expr.c"
748 #include "symbol.c"
749 #include "menu.c"