home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / scripts / kconfig / zconf.y < prev   
Encoding:
Lex Description  |  1995-11-21  |  13.9 KB  |  682 lines

  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, "Linux Kernel 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"
  682.