3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4 * Released under the terms of the GNU GPL v2.0.
14 #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
17 #define DEBUG_PARSE 0x0002
21 extern
int zconflex
(void);
22 static void zconfprint
(const char *err
, ...
);
23 static void zconferror
(const char *err
);
24 static bool zconf_endtoken
(int token
, int starttoken
, int endtoken
);
26 struct symbol
*symbol_hash
[257];
28 #define YYERROR_VERBOSE
36 struct symbol
*symbol
;
50 %token
<string> T_HELPTEXT
62 %token
<string> T_WORD
63 %token
<string> T_STRING
73 %left T_EQUAL T_UNEQUAL
84 #define LKC_DIRECT_LINK
95 | T_MAINMENU prompt nl_or_eof
96 | T_ENDMENU
{ zconfprint
("unexpected 'endmenu' statement"); }
97 | T_ENDIF
{ zconfprint
("unexpected 'endif' statement"); }
98 | T_ENDCHOICE
{ zconfprint
("unexpected 'endchoice' statement"); }
99 |
error nl_or_eof
{ zconfprint
("syntax error"); yyerrok; }
113 config_entry_start: T_CONFIG T_WORD
115 struct symbol
*sym
= sym_lookup
($2, 0);
116 sym
->flags |
= SYMBOL_OPTIONAL
;
118 printd
(DEBUG_PARSE
, "%s:%d:config %s\n", zconf_curname
(), zconf_lineno
(), $2);
121 config_stmt: config_entry_start T_EOL config_option_list
124 printd
(DEBUG_PARSE
, "%s:%d:endconfig\n", zconf_curname
(), zconf_lineno
());
129 | config_option_list config_option T_EOL
130 | config_option_list depends T_EOL
131 | config_option_list help
132 | config_option_list T_EOL
135 config_option: T_TRISTATE prompt_stmt_opt
137 menu_set_type
(S_TRISTATE
);
138 printd
(DEBUG_PARSE
, "%s:%d:tristate\n", zconf_curname
(), zconf_lineno
());
141 config_option: T_BOOLEAN prompt_stmt_opt
143 menu_set_type
(S_BOOLEAN
);
144 printd
(DEBUG_PARSE
, "%s:%d:boolean\n", zconf_curname
(), zconf_lineno
());
147 config_option: T_INT prompt_stmt_opt
149 menu_set_type
(S_INT
);
150 printd
(DEBUG_PARSE
, "%s:%d:int\n", zconf_curname
(), zconf_lineno
());
153 config_option: T_HEX prompt_stmt_opt
155 menu_set_type
(S_HEX
);
156 printd
(DEBUG_PARSE
, "%s:%d:hex\n", zconf_curname
(), zconf_lineno
());
159 config_option: T_STRING prompt_stmt_opt
161 menu_set_type
(S_STRING
);
162 printd
(DEBUG_PARSE
, "%s:%d:string\n", zconf_curname
(), zconf_lineno
());
165 config_option: T_PROMPT prompt if_expr
167 menu_add_prop
(P_PROMPT
, $2, NULL
, $3);
168 printd
(DEBUG_PARSE
, "%s:%d:prompt\n", zconf_curname
(), zconf_lineno
());
171 config_option: T_DEFAULT symbol if_expr
173 menu_add_prop
(P_DEFAULT
, NULL
, $2, $3);
174 printd
(DEBUG_PARSE
, "%s:%d:default\n", zconf_curname
(), zconf_lineno
());
181 struct symbol
*sym
= sym_lookup
(NULL
, 0);
182 sym
->flags |
= SYMBOL_CHOICE
;
184 menu_add_prop
(P_CHOICE
, NULL
, NULL
, NULL
);
185 printd
(DEBUG_PARSE
, "%s:%d:choice\n", zconf_curname
(), zconf_lineno
());
188 choice_entry: choice T_EOL choice_option_list
196 if
(zconf_endtoken
($1, T_CHOICE
, T_ENDCHOICE
)) {
198 printd
(DEBUG_PARSE
, "%s:%d:endchoice\n", zconf_curname
(), zconf_lineno
());
203 choice_entry choice_block choice_end T_EOL
204 | choice_entry choice_block
206 printf
("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu
->file
->name
, current_menu
->lineno
);
212 | choice_option_list choice_option T_EOL
213 | choice_option_list depends T_EOL
214 | choice_option_list help
215 | choice_option_list T_EOL
218 choice_option: T_PROMPT prompt if_expr
220 menu_add_prop
(P_PROMPT
, $2, NULL
, $3);
221 printd
(DEBUG_PARSE
, "%s:%d:prompt\n", zconf_curname
(), zconf_lineno
());
224 choice_option: T_OPTIONAL
226 current_entry
->sym
->flags |
= SYMBOL_OPTIONAL
;
227 printd
(DEBUG_PARSE
, "%s:%d:optional\n", zconf_curname
(), zconf_lineno
());
230 choice_option: T_DEFAULT symbol
232 menu_add_prop
(P_DEFAULT
, NULL
, $2, NULL
);
233 //current_choice->prop->def = $2;
234 printd
(DEBUG_PARSE
, "%s:%d:default\n", zconf_curname
(), zconf_lineno
());
239 | choice_block common_block
246 printd
(DEBUG_PARSE
, "%s:%d:if\n", zconf_curname
(), zconf_lineno
());
247 menu_add_entry
(NULL
);
248 //current_entry->prompt = menu_add_prop(T_IF, NULL, NULL, $2);
256 if
(zconf_endtoken
($1, T_IF
, T_ENDIF
)) {
258 printd
(DEBUG_PARSE
, "%s:%d:endif\n", zconf_curname
(), zconf_lineno
());
263 if T_EOL if_block if_end T_EOL
266 printf
("%s:%d: missing 'endif' for this 'if' statement\n", current_menu
->file
->name
, current_menu
->lineno
);
272 | if_block common_block
274 | if_block choice_stmt
281 menu_add_entry
(NULL
);
282 menu_add_prop
(P_MENU
, $2, NULL
, NULL
);
283 printd
(DEBUG_PARSE
, "%s:%d:menu\n", zconf_curname
(), zconf_lineno
());
286 menu_entry: menu T_EOL depends_list
294 if
(zconf_endtoken
($1, T_MENU
, T_ENDMENU
)) {
296 printd
(DEBUG_PARSE
, "%s:%d:endmenu\n", zconf_curname
(), zconf_lineno
());
301 menu_entry menu_block menu_end T_EOL
302 | menu_entry menu_block
304 printf
("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu
->file
->name
, current_menu
->lineno
);
310 | menu_block common_block
311 | menu_block menu_stmt
312 | menu_block choice_stmt
313 | menu_block
error T_EOL
{ zconfprint
("invalid menu option"); yyerrok; }
316 source: T_SOURCE prompt
319 printd
(DEBUG_PARSE
, "%s:%d:source %s\n", zconf_curname
(), zconf_lineno
(), $2);
322 source_stmt: source T_EOL
329 comment: T_COMMENT prompt
331 menu_add_entry
(NULL
);
332 menu_add_prop
(P_COMMENT
, $2, NULL
, NULL
);
333 printd
(DEBUG_PARSE
, "%s:%d:comment\n", zconf_curname
(), zconf_lineno
());
336 comment_stmt: comment T_EOL depends_list
343 help_start: T_HELP T_EOL
345 printd
(DEBUG_PARSE
, "%s:%d:help\n", zconf_curname
(), zconf_lineno
());
349 help: help_start T_HELPTEXT
351 current_entry
->sym
->help
= $2;
356 depends_list: /* empty */
357 | depends_list depends T_EOL
361 depends: T_DEPENDS T_ON expr
364 printd
(DEBUG_PARSE
, "%s:%d:depends on\n", zconf_curname
(), zconf_lineno
());
369 printd
(DEBUG_PARSE
, "%s:%d:depends\n", zconf_curname
(), zconf_lineno
());
374 printd
(DEBUG_PARSE
, "%s:%d:requires\n", zconf_curname
(), zconf_lineno
());
377 /* prompt statement */
383 menu_add_prop
(P_PROMPT
, $1, NULL
, NULL
);
387 menu_add_prop
(P_PROMPT
, $1, NULL
, $3);
394 end: T_ENDMENU
{ $$
= T_ENDMENU
; }
395 | T_ENDCHOICE
{ $$
= T_ENDCHOICE
; }
396 | T_ENDIF
{ $$
= T_ENDIF
; }
402 if_expr: /* empty */ { $$
= NULL
; }
403 | T_IF expr
{ $$
= $2; }
406 expr: symbol
{ $$
= expr_alloc_symbol
($1); }
407 | symbol T_EQUAL symbol
{ $$
= expr_alloc_comp
(E_EQUAL
, $1, $3); }
408 | symbol T_UNEQUAL symbol
{ $$
= expr_alloc_comp
(E_UNEQUAL
, $1, $3); }
409 | T_OPEN_PAREN expr T_CLOSE_PAREN
{ $$
= $2; }
410 | T_NOT expr
{ $$
= expr_alloc_one
(E_NOT
, $2); }
411 | expr T_OR expr
{ $$
= expr_alloc_two
(E_OR
, $1, $3); }
412 | expr T_AND expr
{ $$
= expr_alloc_two
(E_AND
, $1, $3); }
415 symbol: T_WORD
{ $$
= sym_lookup
($1, 0); free
($1); }
416 | T_STRING
{ $$
= sym_lookup
($1, 1); free
($1); }
421 void conf_parse
(const char *name
)
423 zconf_initscan
(name
);
427 rootmenu.prompt
= menu_add_prop
(P_MENU
, "Broadcom Linux Router Configuration", NULL
, NULL
);
433 menu_finalize
(&rootmenu
);
435 modules_sym
= sym_lookup
("MODULES", 0);
437 sym_change_count
= 1;
440 const char *zconf_tokenname
(int token
)
443 case T_MENU
: return
"menu";
444 case T_ENDMENU
: return
"endmenu";
445 case T_CHOICE
: return
"choice";
446 case T_ENDCHOICE
: return
"endchoice";
447 case T_IF
: return
"if";
448 case T_ENDIF
: return
"endif";
453 static bool zconf_endtoken
(int token
, int starttoken
, int endtoken
)
455 if
(token
!= endtoken
) {
456 zconfprint
("unexpected '%s' within %s block", zconf_tokenname
(token
), zconf_tokenname
(starttoken
));
460 if
(current_menu
->file
!= current_file
) {
461 zconfprint
("'%s' in different file than '%s'", zconf_tokenname
(token
), zconf_tokenname
(starttoken
));
462 zconfprint
("location of the '%s'", zconf_tokenname
(starttoken
));
469 static void zconfprint
(const char *err
, ...
)
473 fprintf
(stderr
, "%s:%d: ", zconf_curname
(), zconf_lineno
());
475 vfprintf
(stderr
, err
, ap
);
477 fprintf
(stderr
, "\n");
480 static void zconferror
(const char *err
)
482 fprintf
(stderr
, "%s:%d: %s\n", zconf_curname
(), zconf_lineno
(), err
);
485 void print_quoted_string
(FILE *out
, const char *str
)
491 while
((p
= strchr
(str
, '"'))) {
494 fprintf
(out
, "%.*s", len
, str
);
502 void print_symbol
(FILE *out
, struct menu
*menu
)
504 struct symbol
*sym
= menu
->sym
;
505 struct property
*prop
;
507 //sym->flags |= SYMBOL_PRINTED;
509 if
(sym_is_choice
(sym
))
510 fprintf
(out
, "choice\n");
512 fprintf
(out
, "config %s\n", sym
->name
);
515 fputs
(" boolean\n", out
);
518 fputs
(" tristate\n", out
);
521 fputs
(" string\n", out
);
524 fputs
(" integer\n", out
);
527 fputs
(" hex\n", out
);
530 fputs
(" ???\n", out
);
533 for
(prop
= sym
->prop
; prop
; prop
= prop
->next
) {
534 if
(prop
->menu
!= menu
)
536 switch
(prop
->type
) {
538 fputs
(" prompt ", out
);
539 print_quoted_string
(out
, prop
->text
);
542 if
(prop
->def
->flags
& SYMBOL_CONST
)
543 print_quoted_string
(out
, prop
->def
->name
);
545 fputs
(prop
->def
->name
, out
);
547 if
(!expr_is_yes
(E_EXPR
(prop
->visible
))) {
549 expr_fprint
(E_EXPR
(prop
->visible
), out
);
554 fputs
( " default ", out
);
555 print_quoted_string
(out
, prop
->def
->name
);
556 if
(!expr_is_yes
(E_EXPR
(prop
->visible
))) {
558 expr_fprint
(E_EXPR
(prop
->visible
), out
);
563 fputs
(" #choice value\n", out
);
566 fprintf
(out
, " unknown prop %d!\n", prop
->type
);
571 int len
= strlen
(sym
->help
);
572 while
(sym
->help
[--len
] == '\n')
574 fprintf
(out
, " help\n%s\n", sym
->help
);
579 void zconfdump
(FILE *out
)
582 struct property
*prop
;
586 menu
= rootmenu.list
;
588 if
((sym
= menu
->sym
))
589 print_symbol
(out
, menu
);
590 else if
((prop
= menu
->prompt
)) {
591 switch
(prop
->type
) {
593 // fputs("\nmainmenu ", out);
594 // print_quoted_string(out, prop->text);
598 fputs
("\ncomment ", out
);
599 print_quoted_string
(out
, prop
->text
);
603 fputs
("\nmenu ", out
);
604 print_quoted_string
(out
, prop
->text
);
608 // fputs("\nsource ", out);
609 // print_quoted_string(out, prop->text);
613 // fputs("\nif\n", out);
617 if
(!expr_is_yes
(E_EXPR
(prop
->visible
))) {
618 fputs
(" depends ", out
);
619 expr_fprint
(E_EXPR
(prop
->visible
), out
);
629 else while
((menu
= menu
->parent
)) {
630 if
(menu
->prompt
&& menu
->prompt
->type
== P_MENU
)
631 fputs
("\nendmenu\n", out
);
640 #include "lex.zconf.c"
641 #include "confdata.c"