kconfig/zconf.y
author "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
Mon Apr 16 15:25:36 2012 +0200 (2012-04-16)
changeset 2941 13e40098fffc
permissions -rw-r--r--
cc/gcc: update Linaro GCC revisions to 2012.04

Update Linaro GCC with the latest available revisions.

The 4.7 revision is also released, but the infrastructure is not yet ready for
it in CT-NG.

Signed-off-by: "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
     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 #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
    18 
    19 #define PRINTD		0x0001
    20 #define DEBUG_PARSE	0x0002
    21 
    22 int cdebug = PRINTD;
    23 
    24 extern int zconflex(void);
    25 static void zconfprint(const char *err, ...);
    26 static void zconf_error(const char *err, ...);
    27 static void zconferror(const char *err);
    28 static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
    29 
    30 struct symbol *symbol_hash[SYMBOL_HASHSIZE];
    31 
    32 static struct menu *current_menu, *current_entry;
    33 
    34 #define YYDEBUG 0
    35 #if YYDEBUG
    36 #define YYERROR_VERBOSE
    37 #endif
    38 %}
    39 %expect 30
    40 
    41 %union
    42 {
    43 	char *string;
    44 	struct file *file;
    45 	struct symbol *symbol;
    46 	struct expr *expr;
    47 	struct menu *menu;
    48 	struct kconf_id *id;
    49 }
    50 
    51 %token <id>T_MAINMENU
    52 %token <id>T_MENU
    53 %token <id>T_ENDMENU
    54 %token <id>T_SOURCE
    55 %token <id>T_CHOICE
    56 %token <id>T_ENDCHOICE
    57 %token <id>T_COMMENT
    58 %token <id>T_CONFIG
    59 %token <id>T_MENUCONFIG
    60 %token <id>T_HELP
    61 %token <string> T_HELPTEXT
    62 %token <id>T_IF
    63 %token <id>T_ENDIF
    64 %token <id>T_DEPENDS
    65 %token <id>T_OPTIONAL
    66 %token <id>T_PROMPT
    67 %token <id>T_TYPE
    68 %token <id>T_DEFAULT
    69 %token <id>T_SELECT
    70 %token <id>T_RANGE
    71 %token <id>T_VISIBLE
    72 %token <id>T_OPTION
    73 %token <id>T_ON
    74 %token <string> T_WORD
    75 %token <string> T_WORD_QUOTE
    76 %token T_UNEQUAL
    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 %nonassoc T_NOT
    85 
    86 %type <string> prompt
    87 %type <symbol> symbol
    88 %type <expr> expr
    89 %type <expr> if_expr
    90 %type <id> end
    91 %type <id> option_name
    92 %type <menu> if_entry menu_entry choice_entry
    93 %type <string> symbol_option_arg word_opt
    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 /* Include zconf.hash.c here so it can see the token constants. */
   104 #include "zconf.hash.c"
   105 %}
   106 
   107 %%
   108 input: nl start | start;
   109 
   110 start: mainmenu_stmt stmt_list | stmt_list;
   111 
   112 stmt_list:
   113 	  /* empty */
   114 	| stmt_list common_stmt
   115 	| stmt_list choice_stmt
   116 	| stmt_list menu_stmt
   117 	| stmt_list end			{ zconf_error("unexpected end statement"); }
   118 	| stmt_list T_WORD error T_EOL	{ zconf_error("unknown statement \"%s\"", $2); }
   119 	| stmt_list option_name error T_EOL
   120 {
   121 	zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
   122 }
   123 	| stmt_list error T_EOL		{ zconf_error("invalid statement"); }
   124 ;
   125 
   126 option_name:
   127 	T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
   128 ;
   129 
   130 common_stmt:
   131 	  T_EOL
   132 	| if_stmt
   133 	| comment_stmt
   134 	| config_stmt
   135 	| menuconfig_stmt
   136 	| source_stmt
   137 ;
   138 
   139 option_error:
   140 	  T_WORD error T_EOL		{ zconf_error("unknown option \"%s\"", $1); }
   141 	| error T_EOL			{ zconf_error("invalid option"); }
   142 ;
   143 
   144 
   145 /* config/menuconfig entry */
   146 
   147 config_entry_start: T_CONFIG T_WORD T_EOL
   148 {
   149 	struct symbol *sym = sym_lookup($2, 0);
   150 	sym->flags |= SYMBOL_OPTIONAL;
   151 	menu_add_entry(sym);
   152 	printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
   153 };
   154 
   155 config_stmt: config_entry_start config_option_list
   156 {
   157 	menu_end_entry();
   158 	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
   159 };
   160 
   161 menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
   162 {
   163 	struct symbol *sym = sym_lookup($2, 0);
   164 	sym->flags |= SYMBOL_OPTIONAL;
   165 	menu_add_entry(sym);
   166 	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
   167 };
   168 
   169 menuconfig_stmt: menuconfig_entry_start config_option_list
   170 {
   171 	if (current_entry->prompt)
   172 		current_entry->prompt->type = P_MENU;
   173 	else
   174 		zconfprint("warning: menuconfig statement without prompt");
   175 	menu_end_entry();
   176 	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
   177 };
   178 
   179 config_option_list:
   180 	  /* empty */
   181 	| config_option_list config_option
   182 	| config_option_list symbol_option
   183 	| config_option_list depends
   184 	| config_option_list help
   185 	| config_option_list option_error
   186 	| config_option_list T_EOL
   187 ;
   188 
   189 config_option: T_TYPE prompt_stmt_opt T_EOL
   190 {
   191 	menu_set_type($1->stype);
   192 	printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
   193 		zconf_curname(), zconf_lineno(),
   194 		$1->stype);
   195 };
   196 
   197 config_option: T_PROMPT prompt if_expr T_EOL
   198 {
   199 	menu_add_prompt(P_PROMPT, $2, $3);
   200 	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
   201 };
   202 
   203 config_option: T_DEFAULT expr if_expr T_EOL
   204 {
   205 	menu_add_expr(P_DEFAULT, $2, $3);
   206 	if ($1->stype != S_UNKNOWN)
   207 		menu_set_type($1->stype);
   208 	printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
   209 		zconf_curname(), zconf_lineno(),
   210 		$1->stype);
   211 };
   212 
   213 config_option: T_SELECT T_WORD if_expr T_EOL
   214 {
   215 	menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
   216 	printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
   217 };
   218 
   219 config_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 
   225 symbol_option: T_OPTION symbol_option_list T_EOL
   226 ;
   227 
   228 symbol_option_list:
   229 	  /* empty */
   230 	| symbol_option_list T_WORD symbol_option_arg
   231 {
   232 	struct kconf_id *id = kconf_id_lookup($2, strlen($2));
   233 	if (id && id->flags & TF_OPTION)
   234 		menu_add_option(id->token, $3);
   235 	else
   236 		zconfprint("warning: ignoring unknown option %s", $2);
   237 	free($2);
   238 };
   239 
   240 symbol_option_arg:
   241 	  /* empty */		{ $$ = NULL; }
   242 	| T_EQUAL prompt	{ $$ = $2; }
   243 ;
   244 
   245 /* choice entry */
   246 
   247 choice: T_CHOICE word_opt T_EOL
   248 {
   249 	struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE);
   250 	sym->flags |= SYMBOL_AUTO;
   251 	menu_add_entry(sym);
   252 	menu_add_expr(P_CHOICE, NULL, NULL);
   253 	printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
   254 };
   255 
   256 choice_entry: choice choice_option_list
   257 {
   258 	$$ = menu_add_menu();
   259 };
   260 
   261 choice_end: end
   262 {
   263 	if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
   264 		menu_end_menu();
   265 		printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
   266 	}
   267 };
   268 
   269 choice_stmt: choice_entry choice_block choice_end
   270 ;
   271 
   272 choice_option_list:
   273 	  /* empty */
   274 	| choice_option_list choice_option
   275 	| choice_option_list depends
   276 	| choice_option_list help
   277 	| choice_option_list T_EOL
   278 	| choice_option_list option_error
   279 ;
   280 
   281 choice_option: T_PROMPT prompt if_expr T_EOL
   282 {
   283 	menu_add_prompt(P_PROMPT, $2, $3);
   284 	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
   285 };
   286 
   287 choice_option: T_TYPE prompt_stmt_opt T_EOL
   288 {
   289 	if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) {
   290 		menu_set_type($1->stype);
   291 		printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
   292 			zconf_curname(), zconf_lineno(),
   293 			$1->stype);
   294 	} else
   295 		YYERROR;
   296 };
   297 
   298 choice_option: T_OPTIONAL T_EOL
   299 {
   300 	current_entry->sym->flags |= SYMBOL_OPTIONAL;
   301 	printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
   302 };
   303 
   304 choice_option: T_DEFAULT T_WORD if_expr T_EOL
   305 {
   306 	if ($1->stype == S_UNKNOWN) {
   307 		menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
   308 		printd(DEBUG_PARSE, "%s:%d:default\n",
   309 			zconf_curname(), zconf_lineno());
   310 	} else
   311 		YYERROR;
   312 };
   313 
   314 choice_block:
   315 	  /* empty */
   316 	| choice_block common_stmt
   317 ;
   318 
   319 /* if entry */
   320 
   321 if_entry: T_IF expr nl
   322 {
   323 	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
   324 	menu_add_entry(NULL);
   325 	menu_add_dep($2);
   326 	$$ = menu_add_menu();
   327 };
   328 
   329 if_end: end
   330 {
   331 	if (zconf_endtoken($1, T_IF, T_ENDIF)) {
   332 		menu_end_menu();
   333 		printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
   334 	}
   335 };
   336 
   337 if_stmt: if_entry if_block if_end
   338 ;
   339 
   340 if_block:
   341 	  /* empty */
   342 	| if_block common_stmt
   343 	| if_block menu_stmt
   344 	| if_block choice_stmt
   345 ;
   346 
   347 /* mainmenu entry */
   348 
   349 mainmenu_stmt: T_MAINMENU prompt nl
   350 {
   351 	menu_add_prompt(P_MENU, $2, NULL);
   352 };
   353 
   354 /* menu entry */
   355 
   356 menu: T_MENU prompt T_EOL
   357 {
   358 	menu_add_entry(NULL);
   359 	menu_add_prompt(P_MENU, $2, NULL);
   360 	printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
   361 };
   362 
   363 menu_entry: menu visibility_list depends_list
   364 {
   365 	$$ = menu_add_menu();
   366 };
   367 
   368 menu_end: end
   369 {
   370 	if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
   371 		menu_end_menu();
   372 		printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
   373 	}
   374 };
   375 
   376 menu_stmt: menu_entry menu_block menu_end
   377 ;
   378 
   379 menu_block:
   380 	  /* empty */
   381 	| menu_block common_stmt
   382 	| menu_block menu_stmt
   383 	| menu_block choice_stmt
   384 ;
   385 
   386 source_stmt: T_SOURCE prompt T_EOL
   387 {
   388 	printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
   389 	zconf_nextfile($2);
   390 };
   391 
   392 /* comment entry */
   393 
   394 comment: T_COMMENT prompt T_EOL
   395 {
   396 	menu_add_entry(NULL);
   397 	menu_add_prompt(P_COMMENT, $2, NULL);
   398 	printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
   399 };
   400 
   401 comment_stmt: comment depends_list
   402 {
   403 	menu_end_entry();
   404 };
   405 
   406 /* help option */
   407 
   408 help_start: T_HELP T_EOL
   409 {
   410 	printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
   411 	zconf_starthelp();
   412 };
   413 
   414 help: help_start T_HELPTEXT
   415 {
   416 	current_entry->help = $2;
   417 };
   418 
   419 /* depends option */
   420 
   421 depends_list:
   422 	  /* empty */
   423 	| depends_list depends
   424 	| depends_list T_EOL
   425 	| depends_list option_error
   426 ;
   427 
   428 depends: T_DEPENDS T_ON expr T_EOL
   429 {
   430 	menu_add_dep($3);
   431 	printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
   432 };
   433 
   434 /* visibility option */
   435 
   436 visibility_list:
   437 	  /* empty */
   438 	| visibility_list visible
   439 	| visibility_list T_EOL
   440 ;
   441 
   442 visible: T_VISIBLE if_expr
   443 {
   444 	menu_add_visibility($2);
   445 };
   446 
   447 /* prompt statement */
   448 
   449 prompt_stmt_opt:
   450 	  /* empty */
   451 	| prompt if_expr
   452 {
   453 	menu_add_prompt(P_PROMPT, $1, $2);
   454 };
   455 
   456 prompt:	  T_WORD
   457 	| T_WORD_QUOTE
   458 ;
   459 
   460 end:	  T_ENDMENU T_EOL	{ $$ = $1; }
   461 	| T_ENDCHOICE T_EOL	{ $$ = $1; }
   462 	| T_ENDIF T_EOL		{ $$ = $1; }
   463 ;
   464 
   465 nl:
   466 	  T_EOL
   467 	| nl T_EOL
   468 ;
   469 
   470 if_expr:  /* empty */			{ $$ = NULL; }
   471 	| T_IF expr			{ $$ = $2; }
   472 ;
   473 
   474 expr:	  symbol				{ $$ = expr_alloc_symbol($1); }
   475 	| symbol T_EQUAL symbol			{ $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
   476 	| symbol T_UNEQUAL symbol		{ $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
   477 	| T_OPEN_PAREN expr T_CLOSE_PAREN	{ $$ = $2; }
   478 	| T_NOT expr				{ $$ = expr_alloc_one(E_NOT, $2); }
   479 	| expr T_OR expr			{ $$ = expr_alloc_two(E_OR, $1, $3); }
   480 	| expr T_AND expr			{ $$ = expr_alloc_two(E_AND, $1, $3); }
   481 ;
   482 
   483 symbol:	  T_WORD	{ $$ = sym_lookup($1, 0); free($1); }
   484 	| T_WORD_QUOTE	{ $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
   485 ;
   486 
   487 word_opt: /* empty */			{ $$ = NULL; }
   488 	| T_WORD
   489 
   490 %%
   491 
   492 void conf_parse(const char *name)
   493 {
   494 	struct symbol *sym;
   495 	int i;
   496 
   497 	zconf_initscan(name);
   498 
   499 	sym_init();
   500 	_menu_init();
   501 	modules_sym = sym_lookup(NULL, 0);
   502 	modules_sym->type = S_BOOLEAN;
   503 	modules_sym->flags |= SYMBOL_AUTO;
   504 	rootmenu.prompt = menu_add_prompt(P_MENU, PACKAGE " Configuration", NULL);
   505 
   506 #if YYDEBUG
   507 	if (getenv("ZCONF_DEBUG"))
   508 		zconfdebug = 1;
   509 #endif
   510 	zconfparse();
   511 	if (zconfnerrs)
   512 		exit(1);
   513 	if (!modules_sym->prop) {
   514 		struct property *prop;
   515 
   516 		prop = prop_alloc(P_DEFAULT, modules_sym);
   517 		prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
   518 	}
   519 
   520 	rootmenu.prompt->text = _(rootmenu.prompt->text);
   521 	rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
   522 
   523 	menu_finalize(&rootmenu);
   524 	for_all_symbols(i, sym) {
   525 		if (sym_check_deps(sym))
   526 			zconfnerrs++;
   527         }
   528 	if (zconfnerrs)
   529 		exit(1);
   530 	sym_set_change_count(1);
   531 }
   532 
   533 static const char *zconf_tokenname(int token)
   534 {
   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";
   542 	case T_DEPENDS:		return "depends";
   543 	case T_VISIBLE:		return "visible";
   544 	}
   545 	return "<token>";
   546 }
   547 
   548 static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
   549 {
   550 	if (id->token != endtoken) {
   551 		zconf_error("unexpected '%s' within %s block",
   552 			kconf_id_strings + id->name, zconf_tokenname(starttoken));
   553 		zconfnerrs++;
   554 		return false;
   555 	}
   556 	if (current_menu->file != current_file) {
   557 		zconf_error("'%s' in different file than '%s'",
   558 			kconf_id_strings + id->name, zconf_tokenname(starttoken));
   559 		fprintf(stderr, "%s:%d: location of the '%s'\n",
   560 			current_menu->file->name, current_menu->lineno,
   561 			zconf_tokenname(starttoken));
   562 		zconfnerrs++;
   563 		return false;
   564 	}
   565 	return true;
   566 }
   567 
   568 static void zconfprint(const char *err, ...)
   569 {
   570 	va_list ap;
   571 
   572 	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 
   579 static void zconf_error(const char *err, ...)
   580 {
   581 	va_list ap;
   582 
   583 	zconfnerrs++;
   584 	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
   585 	va_start(ap, err);
   586 	vfprintf(stderr, err, ap);
   587 	va_end(ap);
   588 	fprintf(stderr, "\n");
   589 }
   590 
   591 static void zconferror(const char *err)
   592 {
   593 #if YYDEBUG
   594 	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
   595 #endif
   596 }
   597 
   598 static void print_quoted_string(FILE *out, const char *str)
   599 {
   600 	const char *p;
   601 	int len;
   602 
   603 	putc('"', out);
   604 	while ((p = strchr(str, '"'))) {
   605 		len = p - str;
   606 		if (len)
   607 			fprintf(out, "%.*s", len, str);
   608 		fputs("\\\"", out);
   609 		str = p + 1;
   610 	}
   611 	fputs(str, out);
   612 	putc('"', out);
   613 }
   614 
   615 static void print_symbol(FILE *out, struct menu *menu)
   616 {
   617 	struct symbol *sym = menu->sym;
   618 	struct property *prop;
   619 
   620 	if (sym_is_choice(sym))
   621 		fprintf(out, "\nchoice\n");
   622 	else
   623 		fprintf(out, "\nconfig %s\n", sym->name);
   624 	switch (sym->type) {
   625 	case S_BOOLEAN:
   626 		fputs("  boolean\n", out);
   627 		break;
   628 	case S_TRISTATE:
   629 		fputs("  tristate\n", out);
   630 		break;
   631 	case S_STRING:
   632 		fputs("  string\n", out);
   633 		break;
   634 	case S_INT:
   635 		fputs("  integer\n", out);
   636 		break;
   637 	case S_HEX:
   638 		fputs("  hex\n", out);
   639 		break;
   640 	default:
   641 		fputs("  ???\n", out);
   642 		break;
   643 	}
   644 	for (prop = sym->prop; prop; prop = prop->next) {
   645 		if (prop->menu != menu)
   646 			continue;
   647 		switch (prop->type) {
   648 		case P_PROMPT:
   649 			fputs("  prompt ", out);
   650 			print_quoted_string(out, prop->text);
   651 			if (!expr_is_yes(prop->visible.expr)) {
   652 				fputs(" if ", out);
   653 				expr_fprint(prop->visible.expr, out);
   654 			}
   655 			fputc('\n', out);
   656 			break;
   657 		case P_DEFAULT:
   658 			fputs( "  default ", out);
   659 			expr_fprint(prop->expr, out);
   660 			if (!expr_is_yes(prop->visible.expr)) {
   661 				fputs(" if ", out);
   662 				expr_fprint(prop->visible.expr, out);
   663 			}
   664 			fputc('\n', out);
   665 			break;
   666 		case P_CHOICE:
   667 			fputs("  #choice value\n", out);
   668 			break;
   669 		case P_SELECT:
   670 			fputs( "  select ", out);
   671 			expr_fprint(prop->expr, out);
   672 			fputc('\n', out);
   673 			break;
   674 		case P_RANGE:
   675 			fputs( "  range ", out);
   676 			expr_fprint(prop->expr, out);
   677 			fputc('\n', out);
   678 			break;
   679 		case P_MENU:
   680 			fputs( "  menu ", out);
   681 			print_quoted_string(out, prop->text);
   682 			fputc('\n', out);
   683 			break;
   684 		default:
   685 			fprintf(out, "  unknown prop %d!\n", prop->type);
   686 			break;
   687 		}
   688 	}
   689 	if (menu->help) {
   690 		int len = strlen(menu->help);
   691 		while (menu->help[--len] == '\n')
   692 			menu->help[len] = 0;
   693 		fprintf(out, "  help\n%s\n", menu->help);
   694 	}
   695 }
   696 
   697 void zconfdump(FILE *out)
   698 {
   699 	struct property *prop;
   700 	struct symbol *sym;
   701 	struct menu *menu;
   702 
   703 	menu = rootmenu.list;
   704 	while (menu) {
   705 		if ((sym = menu->sym))
   706 			print_symbol(out, menu);
   707 		else if ((prop = menu->prompt)) {
   708 			switch (prop->type) {
   709 			case P_COMMENT:
   710 				fputs("\ncomment ", out);
   711 				print_quoted_string(out, prop->text);
   712 				fputs("\n", out);
   713 				break;
   714 			case P_MENU:
   715 				fputs("\nmenu ", out);
   716 				print_quoted_string(out, prop->text);
   717 				fputs("\n", out);
   718 				break;
   719 			default:
   720 				;
   721 			}
   722 			if (!expr_is_yes(prop->visible.expr)) {
   723 				fputs("  depends ", out);
   724 				expr_fprint(prop->visible.expr, out);
   725 				fputc('\n', out);
   726 			}
   727 		}
   728 
   729 		if (menu->list)
   730 			menu = menu->list;
   731 		else if (menu->next)
   732 			menu = menu->next;
   733 		else while ((menu = menu->parent)) {
   734 			if (menu->prompt && menu->prompt->type == P_MENU)
   735 				fputs("\nendmenu\n", out);
   736 			if (menu->next) {
   737 				menu = menu->next;
   738 				break;
   739 			}
   740 		}
   741 	}
   742 }
   743 
   744 #include "lex.zconf.c"
   745 #include "util.c"
   746 #include "confdata.c"
   747 #include "expr.c"
   748 #include "symbol.c"
   749 #include "menu.c"