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.


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