kconfig/zconf.y
author "Yann E. MORIN" <yann.morin.1998@free.fr>
Wed Dec 26 12:15:10 2012 +0100 (2012-12-26)
changeset 3144 481658dd0e7f
permissions -rw-r--r--
libc/eglibc: remove now superfluous config knobs

All eglibc versions we now have support pkgversion and bugurl.

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