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