Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.17-rc5 782 lines 17 kB view raw
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 21int cdebug = PRINTD; 22 23int yylex(void); 24static void yyerror(const char *err); 25static void zconfprint(const char *err, ...); 26static void zconf_error(const char *err, ...); 27static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken); 28 29struct symbol *symbol_hash[SYMBOL_HASHSIZE]; 30 31static 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%% 110input: nl start | start; 111 112start: mainmenu_stmt stmt_list | no_mainmenu_stmt stmt_list; 113 114/* mainmenu entry */ 115 116mainmenu_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 123no_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 134stmt_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 148option_name: 149 T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_IMPLY | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE 150; 151 152common_stmt: 153 T_EOL 154 | if_stmt 155 | comment_stmt 156 | config_stmt 157 | menuconfig_stmt 158 | source_stmt 159; 160 161option_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 169config_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 176config_stmt: config_entry_start config_option_list 177{ 178 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); 179}; 180 181menuconfig_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 188menuconfig_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 197config_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 207config_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 215config_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 221config_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 231config_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 237config_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 243config_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 249symbol_option: T_OPTION symbol_option_list T_EOL 250; 251 252symbol_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 266symbol_option_arg: 267 /* empty */ { $$ = NULL; } 268 | T_EQUAL prompt { $$ = $2; } 269; 270 271/* choice entry */ 272 273choice: 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 283choice_entry: choice choice_option_list 284{ 285 $$ = menu_add_menu(); 286}; 287 288choice_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 296choice_stmt: choice_entry choice_block choice_end 297; 298 299choice_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 308choice_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 314choice_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 325choice_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 331choice_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 341choice_block: 342 /* empty */ 343 | choice_block common_stmt 344; 345 346/* if entry */ 347 348if_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 356if_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 364if_stmt: if_entry if_block if_end 365; 366 367if_block: 368 /* empty */ 369 | if_block common_stmt 370 | if_block menu_stmt 371 | if_block choice_stmt 372; 373 374/* menu entry */ 375 376menu: 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 383menu_entry: menu visibility_list depends_list 384{ 385 $$ = menu_add_menu(); 386}; 387 388menu_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 396menu_stmt: menu_entry menu_block menu_end 397; 398 399menu_block: 400 /* empty */ 401 | menu_block common_stmt 402 | menu_block menu_stmt 403 | menu_block choice_stmt 404; 405 406source_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 415comment: 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 422comment_stmt: comment depends_list 423; 424 425/* help option */ 426 427help_start: T_HELP T_EOL 428{ 429 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); 430 zconf_starthelp(); 431}; 432 433help: 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 451depends_list: 452 /* empty */ 453 | depends_list depends 454 | depends_list T_EOL 455 | depends_list option_error 456; 457 458depends: 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 466visibility_list: 467 /* empty */ 468 | visibility_list visible 469 | visibility_list T_EOL 470; 471 472visible: T_VISIBLE if_expr 473{ 474 menu_add_visibility($2); 475}; 476 477/* prompt statement */ 478 479prompt_stmt_opt: 480 /* empty */ 481 | prompt if_expr 482{ 483 menu_add_prompt(P_PROMPT, $1, $2); 484}; 485 486prompt: T_WORD 487 | T_WORD_QUOTE 488; 489 490end: T_ENDMENU T_EOL { $$ = $1; } 491 | T_ENDCHOICE T_EOL { $$ = $1; } 492 | T_ENDIF T_EOL { $$ = $1; } 493; 494 495nl: 496 T_EOL 497 | nl T_EOL 498; 499 500if_expr: /* empty */ { $$ = NULL; } 501 | T_IF expr { $$ = $2; } 502; 503 504expr: 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 */ 518nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }; 519 520symbol: nonconst_symbol 521 | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } 522; 523 524word_opt: /* empty */ { $$ = NULL; } 525 | T_WORD 526 527%% 528 529void 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 563static 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 578static 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 598static 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 609static 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 621static void yyerror(const char *err) 622{ 623 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); 624} 625 626static 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 643static 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 730void 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"