blob: 2127f1d65170917f53bedf7c70a5bd7f07d2c655 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001%{
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
Roman Zippel7a884882005-11-08 21:34:51 -080014#include "lkc.h"
15
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
17
18#define PRINTD 0x0001
19#define DEBUG_PARSE 0x0002
20
21int cdebug = PRINTD;
22
Masahiro Yamada765f4cd2018-01-12 00:50:50 +090023int yylex(void);
24static void yyerror(const char *err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070025static void zconfprint(const char *err, ...);
Roman Zippela02f0572005-11-08 21:34:53 -080026static void zconf_error(const char *err, ...);
Arnaud Lacombe61f956f2011-05-04 21:14:44 -040027static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken);
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
Andi Kleene66f25d2010-01-13 17:02:44 +010029struct symbol *symbol_hash[SYMBOL_HASHSIZE];
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
31static struct menu *current_menu, *current_entry;
32
Linus Torvalds1da177e2005-04-16 15:20:36 -070033%}
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
35%union
36{
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 char *string;
Roman Zippela02f0572005-11-08 21:34:53 -080038 struct file *file;
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 struct symbol *symbol;
40 struct expr *expr;
41 struct menu *menu;
Arnaud Lacombe61f956f2011-05-04 21:14:44 -040042 const struct kconf_id *id;
Masahiro Yamada3c8f3172018-12-11 20:00:59 +090043 enum symbol_type type;
Masahiro Yamada1175c022018-05-28 18:21:50 +090044 enum variable_flavor flavor;
Linus Torvalds1da177e2005-04-16 15:20:36 -070045}
46
Roman Zippel3370f9f2005-11-08 21:34:52 -080047%token <id>T_MAINMENU
48%token <id>T_MENU
49%token <id>T_ENDMENU
50%token <id>T_SOURCE
51%token <id>T_CHOICE
52%token <id>T_ENDCHOICE
53%token <id>T_COMMENT
54%token <id>T_CONFIG
55%token <id>T_MENUCONFIG
56%token <id>T_HELP
Linus Torvalds1da177e2005-04-16 15:20:36 -070057%token <string> T_HELPTEXT
Roman Zippel3370f9f2005-11-08 21:34:52 -080058%token <id>T_IF
59%token <id>T_ENDIF
60%token <id>T_DEPENDS
Roman Zippel3370f9f2005-11-08 21:34:52 -080061%token <id>T_OPTIONAL
62%token <id>T_PROMPT
Roman Zippel3370f9f2005-11-08 21:34:52 -080063%token <id>T_SELECT
Nicolas Pitre237e3ad2016-11-11 00:10:05 -050064%token <id>T_IMPLY
Roman Zippel3370f9f2005-11-08 21:34:52 -080065%token <id>T_RANGE
Arnaud Lacombe86e187f2010-11-06 18:30:23 -030066%token <id>T_VISIBLE
Roman Zippel3370f9f2005-11-08 21:34:52 -080067%token <id>T_ON
Linus Torvalds1da177e2005-04-16 15:20:36 -070068%token <string> T_WORD
69%token <string> T_WORD_QUOTE
Masahiro Yamadace2164a2018-12-11 20:01:00 +090070%token T_ALLNOCONFIG_Y
Masahiro Yamada3c8f3172018-12-11 20:00:59 +090071%token T_BOOL
Linus Torvalds1da177e2005-04-16 15:20:36 -070072%token T_CLOSE_PAREN
Masahiro Yamadac3d22872018-12-11 20:01:01 +090073%token T_COLON_EQUAL
Masahiro Yamada3c8f3172018-12-11 20:00:59 +090074%token T_DEFAULT
Masahiro Yamadace2164a2018-12-11 20:01:00 +090075%token T_DEFCONFIG_LIST
Masahiro Yamada3c8f3172018-12-11 20:00:59 +090076%token T_DEF_BOOL
77%token T_DEF_TRISTATE
78%token T_HEX
79%token T_INT
Masahiro Yamadace2164a2018-12-11 20:01:00 +090080%token T_MODULES
Linus Torvalds1da177e2005-04-16 15:20:36 -070081%token T_OPEN_PAREN
Masahiro Yamadace2164a2018-12-11 20:01:00 +090082%token T_OPTION
Masahiro Yamadac3d22872018-12-11 20:01:01 +090083%token T_PLUS_EQUAL
Masahiro Yamada3c8f3172018-12-11 20:00:59 +090084%token T_STRING
85%token T_TRISTATE
Roman Zippel3370f9f2005-11-08 21:34:52 -080086%token T_EOL
Masahiro Yamada9ced3bd2018-05-28 18:21:49 +090087%token <string> T_ASSIGN_VAL
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
89%left T_OR
90%left T_AND
91%left T_EQUAL T_UNEQUAL
Jan Beulich31847b62015-06-15 13:00:21 +010092%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL
Linus Torvalds1da177e2005-04-16 15:20:36 -070093%nonassoc T_NOT
94
95%type <string> prompt
Ulf Magnusson26e47a32017-10-08 19:11:18 +020096%type <symbol> nonconst_symbol
Linus Torvalds1da177e2005-04-16 15:20:36 -070097%type <symbol> symbol
Masahiro Yamada3c8f3172018-12-11 20:00:59 +090098%type <type> type logic_type default
Linus Torvalds1da177e2005-04-16 15:20:36 -070099%type <expr> expr
100%type <expr> if_expr
Roman Zippela02f0572005-11-08 21:34:53 -0800101%type <id> end
Roman Zippela02f0572005-11-08 21:34:53 -0800102%type <menu> if_entry menu_entry choice_entry
Masahiro Yamadace2164a2018-12-11 20:01:00 +0900103%type <string> word_opt assign_val
Masahiro Yamadac3d22872018-12-11 20:01:01 +0900104%type <flavor> assign_op
Roman Zippela02f0572005-11-08 21:34:53 -0800105
106%destructor {
107 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
108 $$->file->name, $$->lineno);
109 if (current_menu == $$)
110 menu_end_menu();
111} if_entry menu_entry choice_entry
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
Josh Triplett1456edb2009-10-15 11:03:20 -0700113%{
Ulf Magnussonc8734432017-10-05 05:06:48 +0200114/* Include kconf_id.c here so it can see the token constants. */
Linus Torvaldsbb3290d2017-08-19 10:17:02 -0700115#include "kconf_id.c"
Josh Triplett1456edb2009-10-15 11:03:20 -0700116%}
117
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118%%
Masahiro Yamadacc66bca2018-12-11 20:00:49 +0900119input: mainmenu_stmt stmt_list | stmt_list;
Ulf Magnusson0724a7c2017-10-08 19:11:21 +0200120
121/* mainmenu entry */
122
Masahiro Yamada56869d42018-08-09 15:47:06 +0900123mainmenu_stmt: T_MAINMENU prompt T_EOL
Ulf Magnusson0724a7c2017-10-08 19:11:21 +0200124{
125 menu_add_prompt(P_MENU, $2, NULL);
126};
127
Roman Zippela02f0572005-11-08 21:34:53 -0800128stmt_list:
129 /* empty */
130 | stmt_list common_stmt
131 | stmt_list choice_stmt
132 | stmt_list menu_stmt
Roman Zippela02f0572005-11-08 21:34:53 -0800133 | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
Roman Zippela02f0572005-11-08 21:34:53 -0800134 | stmt_list error T_EOL { zconf_error("invalid statement"); }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135;
136
Roman Zippela02f0572005-11-08 21:34:53 -0800137common_stmt:
Masahiro Yamadacc66bca2018-12-11 20:00:49 +0900138 if_stmt
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 | comment_stmt
140 | config_stmt
141 | menuconfig_stmt
142 | source_stmt
Masahiro Yamada9ced3bd2018-05-28 18:21:49 +0900143 | assignment_stmt
Roman Zippela02f0572005-11-08 21:34:53 -0800144;
145
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146/* config/menuconfig entry */
147
Ulf Magnusson26e47a32017-10-08 19:11:18 +0200148config_entry_start: T_CONFIG nonconst_symbol T_EOL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149{
Ulf Magnusson26e47a32017-10-08 19:11:18 +0200150 $2->flags |= SYMBOL_OPTIONAL;
151 menu_add_entry($2);
152 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153};
154
155config_stmt: config_entry_start config_option_list
156{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
158};
159
Ulf Magnusson26e47a32017-10-08 19:11:18 +0200160menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161{
Ulf Magnusson26e47a32017-10-08 19:11:18 +0200162 $2->flags |= SYMBOL_OPTIONAL;
163 menu_add_entry($2);
164 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165};
166
167menuconfig_stmt: menuconfig_entry_start config_option_list
168{
169 if (current_entry->prompt)
170 current_entry->prompt->type = P_MENU;
171 else
172 zconfprint("warning: menuconfig statement without prompt");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
174};
175
176config_option_list:
177 /* empty */
178 | config_option_list config_option
179 | config_option_list depends
180 | config_option_list help
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181;
182
Masahiro Yamada3c8f3172018-12-11 20:00:59 +0900183config_option: type prompt_stmt_opt T_EOL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184{
Masahiro Yamada3c8f3172018-12-11 20:00:59 +0900185 menu_set_type($1);
Roman Zippel3370f9f2005-11-08 21:34:52 -0800186 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
187 zconf_curname(), zconf_lineno(),
Masahiro Yamada3c8f3172018-12-11 20:00:59 +0900188 $1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189};
190
191config_option: T_PROMPT prompt if_expr T_EOL
192{
193 menu_add_prompt(P_PROMPT, $2, $3);
194 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
195};
196
Masahiro Yamada3c8f3172018-12-11 20:00:59 +0900197config_option: default expr if_expr T_EOL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198{
199 menu_add_expr(P_DEFAULT, $2, $3);
Masahiro Yamada3c8f3172018-12-11 20:00:59 +0900200 if ($1 != S_UNKNOWN)
201 menu_set_type($1);
Roman Zippel3370f9f2005-11-08 21:34:52 -0800202 printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
203 zconf_curname(), zconf_lineno(),
Masahiro Yamada3c8f3172018-12-11 20:00:59 +0900204 $1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205};
206
Ulf Magnusson26e47a32017-10-08 19:11:18 +0200207config_option: T_SELECT nonconst_symbol if_expr T_EOL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208{
Ulf Magnusson26e47a32017-10-08 19:11:18 +0200209 menu_add_symbol(P_SELECT, $2, $3);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
211};
212
Ulf Magnusson26e47a32017-10-08 19:11:18 +0200213config_option: T_IMPLY nonconst_symbol if_expr T_EOL
Nicolas Pitre237e3ad2016-11-11 00:10:05 -0500214{
Ulf Magnusson26e47a32017-10-08 19:11:18 +0200215 menu_add_symbol(P_IMPLY, $2, $3);
Nicolas Pitre237e3ad2016-11-11 00:10:05 -0500216 printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
217};
218
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219config_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
Masahiro Yamadace2164a2018-12-11 20:01:00 +0900225config_option: T_OPTION T_MODULES T_EOL
Roman Zippelf6a88aa2006-06-08 22:12:44 -0700226{
Masahiro Yamadace2164a2018-12-11 20:01:00 +0900227 menu_add_option_modules();
Roman Zippelf6a88aa2006-06-08 22:12:44 -0700228};
229
Masahiro Yamadace2164a2018-12-11 20:01:00 +0900230config_option: T_OPTION T_DEFCONFIG_LIST T_EOL
231{
232 menu_add_option_defconfig_list();
233};
234
235config_option: T_OPTION T_ALLNOCONFIG_Y T_EOL
236{
237 menu_add_option_allnoconfig_y();
238};
Roman Zippelf6a88aa2006-06-08 22:12:44 -0700239
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240/* choice entry */
241
Roman Zippel5a1aa8a2008-02-29 05:11:50 +0100242choice: T_CHOICE word_opt T_EOL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243{
Roman Zippel5a1aa8a2008-02-29 05:11:50 +0100244 struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE);
Dirk Gouders693359f2018-07-03 14:43:31 +0200245 sym->flags |= SYMBOL_NO_WRITE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 menu_add_entry(sym);
247 menu_add_expr(P_CHOICE, NULL, NULL);
Masahiro Yamadabf0bbdc2018-02-20 20:40:29 +0900248 free($2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
250};
251
252choice_entry: choice choice_option_list
253{
Roman Zippela02f0572005-11-08 21:34:53 -0800254 $$ = menu_add_menu();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255};
256
257choice_end: end
258{
259 if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
260 menu_end_menu();
261 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
262 }
263};
264
Roman Zippela02f0572005-11-08 21:34:53 -0800265choice_stmt: choice_entry choice_block choice_end
266;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267
268choice_option_list:
269 /* empty */
270 | choice_option_list choice_option
271 | choice_option_list depends
272 | choice_option_list help
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273;
274
275choice_option: T_PROMPT prompt if_expr T_EOL
276{
277 menu_add_prompt(P_PROMPT, $2, $3);
278 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
279};
280
Masahiro Yamada3c8f3172018-12-11 20:00:59 +0900281choice_option: logic_type prompt_stmt_opt T_EOL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282{
Masahiro Yamada3c8f3172018-12-11 20:00:59 +0900283 menu_set_type($1);
284 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
285 zconf_curname(), zconf_lineno(), $1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286};
287
288choice_option: T_OPTIONAL T_EOL
289{
290 current_entry->sym->flags |= SYMBOL_OPTIONAL;
291 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
292};
293
Ulf Magnusson26e47a32017-10-08 19:11:18 +0200294choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295{
Masahiro Yamada3c8f3172018-12-11 20:00:59 +0900296 menu_add_symbol(P_DEFAULT, $2, $3);
297 printd(DEBUG_PARSE, "%s:%d:default\n",
298 zconf_curname(), zconf_lineno());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299};
300
Masahiro Yamada3c8f3172018-12-11 20:00:59 +0900301type:
302 logic_type
303 | T_INT { $$ = S_INT; }
304 | T_HEX { $$ = S_HEX; }
305 | T_STRING { $$ = S_STRING; }
306
307logic_type:
308 T_BOOL { $$ = S_BOOLEAN; }
309 | T_TRISTATE { $$ = S_TRISTATE; }
310
311default:
312 T_DEFAULT { $$ = S_UNKNOWN; }
313 | T_DEF_BOOL { $$ = S_BOOLEAN; }
314 | T_DEF_TRISTATE { $$ = S_TRISTATE; }
315
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316choice_block:
317 /* empty */
Roman Zippela02f0572005-11-08 21:34:53 -0800318 | choice_block common_stmt
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319;
320
321/* if entry */
322
Dirk Goudersb2d00d72018-06-21 15:30:54 +0200323if_entry: T_IF expr T_EOL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324{
325 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
326 menu_add_entry(NULL);
327 menu_add_dep($2);
Roman Zippela02f0572005-11-08 21:34:53 -0800328 $$ = menu_add_menu();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329};
330
331if_end: end
332{
333 if (zconf_endtoken($1, T_IF, T_ENDIF)) {
334 menu_end_menu();
335 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
336 }
337};
338
Masahiro Yamada48917962018-12-11 20:00:54 +0900339if_stmt: if_entry stmt_list if_end
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340;
341
342/* menu entry */
343
344menu: T_MENU prompt T_EOL
345{
346 menu_add_entry(NULL);
blaisorblade@yahoo.itfb7f6ff2005-07-28 17:56:25 +0200347 menu_add_prompt(P_MENU, $2, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
349};
350
Masahiro Yamada1f31be92018-12-11 20:00:56 +0900351menu_entry: menu menu_option_list
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352{
Roman Zippela02f0572005-11-08 21:34:53 -0800353 $$ = menu_add_menu();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354};
355
356menu_end: end
357{
358 if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
359 menu_end_menu();
360 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
361 }
362};
363
Masahiro Yamada94d4e1b2018-12-11 20:00:55 +0900364menu_stmt: menu_entry stmt_list menu_end
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365;
366
Masahiro Yamada1f31be92018-12-11 20:00:56 +0900367menu_option_list:
368 /* empty */
369 | menu_option_list visible
370 | menu_option_list depends
371;
372
Roman Zippela02f0572005-11-08 21:34:53 -0800373source_stmt: T_SOURCE prompt T_EOL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
Roman Zippela02f0572005-11-08 21:34:53 -0800376 zconf_nextfile($2);
Ulf Magnusson24161a62017-10-08 19:11:19 +0200377 free($2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378};
379
380/* comment entry */
381
382comment: T_COMMENT prompt T_EOL
383{
384 menu_add_entry(NULL);
blaisorblade@yahoo.itfb7f6ff2005-07-28 17:56:25 +0200385 menu_add_prompt(P_COMMENT, $2, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
387};
388
Masahiro Yamada4b5ec812018-12-11 20:00:57 +0900389comment_stmt: comment comment_option_list
390;
391
392comment_option_list:
393 /* empty */
394 | comment_option_list depends
Ulf Magnussondf60f4b2017-10-09 00:14:48 +0200395;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396
397/* help option */
398
399help_start: T_HELP T_EOL
400{
401 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
402 zconf_starthelp();
403};
404
405help: help_start T_HELPTEXT
406{
Ulf Magnusson6479f322018-01-12 07:47:47 +0100407 if (current_entry->help) {
408 free(current_entry->help);
409 zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used",
410 current_entry->sym->name ?: "<choice>");
411 }
Ulf Magnusson1b9eda22018-01-31 10:34:30 +0100412
413 /* Is the help text empty or all whitespace? */
414 if ($2[strspn($2, " \f\n\r\t\v")] == '\0')
415 zconfprint("warning: '%s' defined with blank help text",
416 current_entry->sym->name ?: "<choice>");
417
Sam Ravnborg03d29122007-07-21 00:00:36 +0200418 current_entry->help = $2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419};
420
421/* depends option */
422
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423depends: T_DEPENDS T_ON expr T_EOL
424{
425 menu_add_dep($3);
426 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427};
428
Arnaud Lacombe86e187f2010-11-06 18:30:23 -0300429/* visibility option */
Masahiro Yamada413cd192018-12-11 20:00:46 +0900430visible: T_VISIBLE if_expr T_EOL
Arnaud Lacombe86e187f2010-11-06 18:30:23 -0300431{
432 menu_add_visibility($2);
433};
434
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435/* prompt statement */
436
437prompt_stmt_opt:
438 /* empty */
439 | prompt if_expr
440{
blaisorblade@yahoo.itfb7f6ff2005-07-28 17:56:25 +0200441 menu_add_prompt(P_PROMPT, $1, $2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442};
443
444prompt: T_WORD
445 | T_WORD_QUOTE
446;
447
Roman Zippela02f0572005-11-08 21:34:53 -0800448end: T_ENDMENU T_EOL { $$ = $1; }
449 | T_ENDCHOICE T_EOL { $$ = $1; }
450 | T_ENDIF T_EOL { $$ = $1; }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451;
452
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453if_expr: /* empty */ { $$ = NULL; }
454 | T_IF expr { $$ = $2; }
455;
456
457expr: symbol { $$ = expr_alloc_symbol($1); }
Jan Beulich31847b62015-06-15 13:00:21 +0100458 | symbol T_LESS symbol { $$ = expr_alloc_comp(E_LTH, $1, $3); }
459 | symbol T_LESS_EQUAL symbol { $$ = expr_alloc_comp(E_LEQ, $1, $3); }
460 | symbol T_GREATER symbol { $$ = expr_alloc_comp(E_GTH, $1, $3); }
461 | symbol T_GREATER_EQUAL symbol { $$ = expr_alloc_comp(E_GEQ, $1, $3); }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
463 | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
464 | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
465 | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
466 | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
467 | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
468;
469
Ulf Magnusson26e47a32017-10-08 19:11:18 +0200470/* For symbol definitions, selects, etc., where quotes are not accepted */
471nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); };
472
473symbol: nonconst_symbol
Roman Zippel5a1aa8a2008-02-29 05:11:50 +0100474 | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475;
476
Roman Zippel5a1aa8a2008-02-29 05:11:50 +0100477word_opt: /* empty */ { $$ = NULL; }
478 | T_WORD
479
Masahiro Yamada9ced3bd2018-05-28 18:21:49 +0900480/* assignment statement */
481
Masahiro Yamada171a5152018-12-11 20:01:02 +0900482assignment_stmt: T_WORD assign_op assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); }
Masahiro Yamadac3d22872018-12-11 20:01:01 +0900483
484assign_op:
485 T_EQUAL { $$ = VAR_RECURSIVE; }
486 | T_COLON_EQUAL { $$ = VAR_SIMPLE; }
487 | T_PLUS_EQUAL { $$ = VAR_APPEND; }
488;
Masahiro Yamada9ced3bd2018-05-28 18:21:49 +0900489
490assign_val:
491 /* empty */ { $$ = xstrdup(""); };
492 | T_ASSIGN_VAL
493;
494
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495%%
496
497void conf_parse(const char *name)
498{
499 struct symbol *sym;
500 int i;
501
502 zconf_initscan(name);
503
nir.tzachar@gmail.com692d97c2009-11-25 12:28:43 +0200504 _menu_init();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505
Roman Zippela02f0572005-11-08 21:34:53 -0800506 if (getenv("ZCONF_DEBUG"))
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900507 yydebug = 1;
508 yyparse();
Masahiro Yamada9ced3bd2018-05-28 18:21:49 +0900509
510 /* Variables are expanded in the parse phase. We can free them here. */
511 variable_all_del();
512
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900513 if (yynerrs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 exit(1);
Yann E. MORIN6902dcc2013-09-03 17:07:18 +0200515 if (!modules_sym)
516 modules_sym = sym_find( "n" );
Arnaud Lacombef6ce00b2010-09-09 21:17:26 -0400517
Masahiro Yamada96d8e482018-05-28 18:21:42 +0900518 if (!menu_has_prompt(&rootmenu)) {
519 current_entry = &rootmenu;
Masahiro Yamada137c0112018-05-28 18:21:44 +0900520 menu_add_prompt(P_MENU, "Main menu", NULL);
Masahiro Yamada96d8e482018-05-28 18:21:42 +0900521 }
Arnaud Lacombef6ce00b2010-09-09 21:17:26 -0400522
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 menu_finalize(&rootmenu);
524 for_all_symbols(i, sym) {
Sam Ravnborg5447d342007-05-06 09:20:10 +0200525 if (sym_check_deps(sym))
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900526 yynerrs++;
Masahiro Yamadabb66fc62014-06-10 19:08:13 +0900527 }
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900528 if (yynerrs)
Sam Ravnborg5447d342007-05-06 09:20:10 +0200529 exit(1);
Karsten Wiesebfc10002006-12-13 00:34:07 -0800530 sym_set_change_count(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531}
532
Josh Triplett65166572009-10-15 12:13:36 -0700533static const char *zconf_tokenname(int token)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534{
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";
Roman Zippela02f0572005-11-08 21:34:53 -0800542 case T_DEPENDS: return "depends";
Arnaud Lacombe86e187f2010-11-06 18:30:23 -0300543 case T_VISIBLE: return "visible";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 }
545 return "<token>";
546}
547
Arnaud Lacombe61f956f2011-05-04 21:14:44 -0400548static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549{
Roman Zippela02f0572005-11-08 21:34:53 -0800550 if (id->token != endtoken) {
551 zconf_error("unexpected '%s' within %s block",
Linus Torvaldsbb3290d2017-08-19 10:17:02 -0700552 id->name, zconf_tokenname(starttoken));
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900553 yynerrs++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 return false;
555 }
556 if (current_menu->file != current_file) {
Roman Zippela02f0572005-11-08 21:34:53 -0800557 zconf_error("'%s' in different file than '%s'",
Linus Torvaldsbb3290d2017-08-19 10:17:02 -0700558 id->name, zconf_tokenname(starttoken));
Roman Zippela02f0572005-11-08 21:34:53 -0800559 fprintf(stderr, "%s:%d: location of the '%s'\n",
560 current_menu->file->name, current_menu->lineno,
561 zconf_tokenname(starttoken));
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900562 yynerrs++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 return false;
564 }
565 return true;
566}
567
568static void zconfprint(const char *err, ...)
569{
570 va_list ap;
571
Roman Zippela02f0572005-11-08 21:34:53 -0800572 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
579static void zconf_error(const char *err, ...)
580{
581 va_list ap;
582
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900583 yynerrs++;
Roman Zippela02f0572005-11-08 21:34:53 -0800584 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 va_start(ap, err);
586 vfprintf(stderr, err, ap);
587 va_end(ap);
588 fprintf(stderr, "\n");
589}
590
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900591static void yyerror(const char *err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592{
593 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594}
595
Josh Triplett65166572009-10-15 12:13:36 -0700596static void print_quoted_string(FILE *out, const char *str)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597{
598 const char *p;
599 int len;
600
601 putc('"', out);
602 while ((p = strchr(str, '"'))) {
603 len = p - str;
604 if (len)
605 fprintf(out, "%.*s", len, str);
606 fputs("\\\"", out);
607 str = p + 1;
608 }
609 fputs(str, out);
610 putc('"', out);
611}
612
Josh Triplett65166572009-10-15 12:13:36 -0700613static void print_symbol(FILE *out, struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614{
615 struct symbol *sym = menu->sym;
616 struct property *prop;
617
618 if (sym_is_choice(sym))
Li Zefanc6ccc302010-04-14 11:44:20 +0800619 fprintf(out, "\nchoice\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 else
Li Zefanc6ccc302010-04-14 11:44:20 +0800621 fprintf(out, "\nconfig %s\n", sym->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 switch (sym->type) {
623 case S_BOOLEAN:
Masahiro Yamadab92d8042017-12-16 00:38:02 +0900624 fputs(" bool\n", out);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 break;
626 case S_TRISTATE:
627 fputs(" tristate\n", out);
628 break;
629 case S_STRING:
630 fputs(" string\n", out);
631 break;
632 case S_INT:
633 fputs(" integer\n", out);
634 break;
635 case S_HEX:
636 fputs(" hex\n", out);
637 break;
638 default:
639 fputs(" ???\n", out);
640 break;
641 }
642 for (prop = sym->prop; prop; prop = prop->next) {
643 if (prop->menu != menu)
644 continue;
645 switch (prop->type) {
646 case P_PROMPT:
647 fputs(" prompt ", out);
648 print_quoted_string(out, prop->text);
649 if (!expr_is_yes(prop->visible.expr)) {
650 fputs(" if ", out);
651 expr_fprint(prop->visible.expr, out);
652 }
653 fputc('\n', out);
654 break;
655 case P_DEFAULT:
656 fputs( " default ", out);
657 expr_fprint(prop->expr, out);
658 if (!expr_is_yes(prop->visible.expr)) {
659 fputs(" if ", out);
660 expr_fprint(prop->visible.expr, out);
661 }
662 fputc('\n', out);
663 break;
664 case P_CHOICE:
665 fputs(" #choice value\n", out);
666 break;
Li Zefanc6ccc302010-04-14 11:44:20 +0800667 case P_SELECT:
668 fputs( " select ", out);
669 expr_fprint(prop->expr, out);
670 fputc('\n', out);
671 break;
Nicolas Pitre237e3ad2016-11-11 00:10:05 -0500672 case P_IMPLY:
673 fputs( " imply ", out);
674 expr_fprint(prop->expr, out);
675 fputc('\n', out);
676 break;
Li Zefanc6ccc302010-04-14 11:44:20 +0800677 case P_RANGE:
678 fputs( " range ", out);
679 expr_fprint(prop->expr, out);
680 fputc('\n', out);
681 break;
682 case P_MENU:
683 fputs( " menu ", out);
684 print_quoted_string(out, prop->text);
685 fputc('\n', out);
686 break;
Dirk Goudersecd53ac2018-06-22 21:27:38 +0200687 case P_SYMBOL:
688 fputs( " symbol ", out);
689 fprintf(out, "%s\n", prop->sym->name);
690 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 default:
692 fprintf(out, " unknown prop %d!\n", prop->type);
693 break;
694 }
695 }
Sam Ravnborg03d29122007-07-21 00:00:36 +0200696 if (menu->help) {
697 int len = strlen(menu->help);
698 while (menu->help[--len] == '\n')
699 menu->help[len] = 0;
700 fprintf(out, " help\n%s\n", menu->help);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702}
703
704void zconfdump(FILE *out)
705{
706 struct property *prop;
707 struct symbol *sym;
708 struct menu *menu;
709
710 menu = rootmenu.list;
711 while (menu) {
712 if ((sym = menu->sym))
713 print_symbol(out, menu);
714 else if ((prop = menu->prompt)) {
715 switch (prop->type) {
716 case P_COMMENT:
717 fputs("\ncomment ", out);
718 print_quoted_string(out, prop->text);
719 fputs("\n", out);
720 break;
721 case P_MENU:
722 fputs("\nmenu ", out);
723 print_quoted_string(out, prop->text);
724 fputs("\n", out);
725 break;
726 default:
727 ;
728 }
729 if (!expr_is_yes(prop->visible.expr)) {
730 fputs(" depends ", out);
731 expr_fprint(prop->visible.expr, out);
732 fputc('\n', out);
733 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 }
735
736 if (menu->list)
737 menu = menu->list;
738 else if (menu->next)
739 menu = menu->next;
740 else while ((menu = menu->parent)) {
741 if (menu->prompt && menu->prompt->type == P_MENU)
742 fputs("\nendmenu\n", out);
743 if (menu->next) {
744 menu = menu->next;
745 break;
746 }
747 }
748 }
749}
750
Arnaud Lacombe378dbb22011-05-23 02:08:52 -0400751#include "zconf.lex.c"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752#include "util.c"
753#include "confdata.c"
754#include "expr.c"
755#include "symbol.c"
756#include "menu.c"
Masahiro Yamada104daea2018-05-28 18:21:40 +0900757#include "preprocess.c"