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