mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	[PATCH] kconfig: improve error handling in the parser
Add a few error tokens to the parser to catch common errors and print more descriptive error messages. Signed-off-by: Roman Zippel <zippel@linux-m68k.org> Cc: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
		
							parent
							
								
									3370f9f0d9
								
							
						
					
					
						commit
						a02f0570ae
					
				
					 6 changed files with 546 additions and 452 deletions
				
			
		| 
						 | 
				
			
			@ -323,7 +323,7 @@ void zconffree (void *  );
 | 
			
		|||
 | 
			
		||||
/* Begin user sect3 */
 | 
			
		||||
 | 
			
		||||
#define zconfwrap(n) 1
 | 
			
		||||
#define zconfwrap() 1
 | 
			
		||||
#define YY_SKIP_YYWRAP
 | 
			
		||||
 | 
			
		||||
typedef unsigned char YY_CHAR;
 | 
			
		||||
| 
						 | 
				
			
			@ -686,10 +686,10 @@ struct yy_trans_info
 | 
			
		|||
static yyconst flex_int16_t yy_accept[61] =
 | 
			
		||||
    {   0,
 | 
			
		||||
        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 | 
			
		||||
       34,    5,    4,    3,    2,    7,    8,    6,   32,   29,
 | 
			
		||||
       34,    5,    4,    2,    3,    7,    8,    6,   32,   29,
 | 
			
		||||
       31,   24,   28,   27,   26,   22,   17,   13,   16,   20,
 | 
			
		||||
       22,   11,   12,   19,   19,   14,   22,   22,    4,    3,
 | 
			
		||||
        2,    2,    1,    6,   32,   29,   31,   30,   24,   23,
 | 
			
		||||
       22,   11,   12,   19,   19,   14,   22,   22,    4,    2,
 | 
			
		||||
        3,    3,    1,    6,   32,   29,   31,   30,   24,   23,
 | 
			
		||||
       26,   25,   15,   20,    9,   19,   19,   21,   10,   18
 | 
			
		||||
    } ;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -753,6 +753,11 @@ char *zconftext;
 | 
			
		|||
 | 
			
		||||
#define START_STRSIZE	16
 | 
			
		||||
 | 
			
		||||
static struct {
 | 
			
		||||
	struct file *file;
 | 
			
		||||
	int lineno;
 | 
			
		||||
} current_pos;
 | 
			
		||||
 | 
			
		||||
static char *text;
 | 
			
		||||
static int text_size, text_asize;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -766,7 +771,7 @@ struct buffer *current_buf;
 | 
			
		|||
static int last_ts, first_ts;
 | 
			
		||||
 | 
			
		||||
static void zconf_endhelp(void);
 | 
			
		||||
static struct buffer *zconf_endfile(void);
 | 
			
		||||
static void zconf_endfile(void);
 | 
			
		||||
 | 
			
		||||
void new_string(void)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -993,17 +998,17 @@ do_action:	/* This label is used only to access EOF actions. */
 | 
			
		|||
	{ /* beginning of action switch */
 | 
			
		||||
case 1:
 | 
			
		||||
/* rule 1 can match eol */
 | 
			
		||||
YY_RULE_SETUP
 | 
			
		||||
current_file->lineno++;
 | 
			
		||||
	YY_BREAK
 | 
			
		||||
case 2:
 | 
			
		||||
/* rule 2 can match eol */
 | 
			
		||||
YY_RULE_SETUP
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
	current_file->lineno++;
 | 
			
		||||
	return T_EOL;
 | 
			
		||||
}
 | 
			
		||||
	YY_BREAK
 | 
			
		||||
case 3:
 | 
			
		||||
/* rule 3 can match eol */
 | 
			
		||||
YY_RULE_SETUP
 | 
			
		||||
current_file->lineno++; return T_EOL;
 | 
			
		||||
 | 
			
		||||
	YY_BREAK
 | 
			
		||||
case 4:
 | 
			
		||||
YY_RULE_SETUP
 | 
			
		||||
| 
						 | 
				
			
			@ -1023,8 +1028,10 @@ case 6:
 | 
			
		|||
YY_RULE_SETUP
 | 
			
		||||
{
 | 
			
		||||
		struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
 | 
			
		||||
		if (id && id->flags & TF_COMMAND) {
 | 
			
		||||
		BEGIN(PARAM);
 | 
			
		||||
		current_pos.file = current_file;
 | 
			
		||||
		current_pos.lineno = current_file->lineno;
 | 
			
		||||
		if (id && id->flags & TF_COMMAND) {
 | 
			
		||||
			zconflval.id = id;
 | 
			
		||||
			return id->token;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1040,7 +1047,11 @@ YY_RULE_SETUP
 | 
			
		|||
case 8:
 | 
			
		||||
/* rule 8 can match eol */
 | 
			
		||||
YY_RULE_SETUP
 | 
			
		||||
current_file->lineno++; BEGIN(INITIAL);
 | 
			
		||||
{
 | 
			
		||||
		BEGIN(INITIAL);
 | 
			
		||||
		current_file->lineno++;
 | 
			
		||||
		return T_EOL;
 | 
			
		||||
	}
 | 
			
		||||
	YY_BREAK
 | 
			
		||||
 | 
			
		||||
case 9:
 | 
			
		||||
| 
						 | 
				
			
			@ -1246,9 +1257,9 @@ case YY_STATE_EOF(HELP):
 | 
			
		|||
case YY_STATE_EOF(INITIAL):
 | 
			
		||||
case YY_STATE_EOF(COMMAND):
 | 
			
		||||
{
 | 
			
		||||
	if (current_buf) {
 | 
			
		||||
	if (current_file) {
 | 
			
		||||
		zconf_endfile();
 | 
			
		||||
		return T_EOF;
 | 
			
		||||
		return T_EOL;
 | 
			
		||||
	}
 | 
			
		||||
	fclose(zconfin);
 | 
			
		||||
	yyterminate();
 | 
			
		||||
| 
						 | 
				
			
			@ -1958,7 +1969,7 @@ YY_BUFFER_STATE zconf_scan_buffer  (char * base, yy_size_t  size )
 | 
			
		|||
 | 
			
		||||
/** Setup the input buffer state to scan a string. The next call to zconflex() will
 | 
			
		||||
 * scan from a @e copy of @a str.
 | 
			
		||||
 * @param str a NUL-terminated string to scan
 | 
			
		||||
 * @param yy_str a NUL-terminated string to scan
 | 
			
		||||
 * 
 | 
			
		||||
 * @return the newly allocated buffer state object.
 | 
			
		||||
 * @note If you want to scan bytes that may contain NUL values, then use
 | 
			
		||||
| 
						 | 
				
			
			@ -2276,7 +2287,7 @@ void zconf_nextfile(const char *name)
 | 
			
		|||
	current_file = file;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct buffer *zconf_endfile(void)
 | 
			
		||||
static void zconf_endfile(void)
 | 
			
		||||
{
 | 
			
		||||
	struct buffer *parent;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2292,23 +2303,15 @@ static struct buffer *zconf_endfile(void)
 | 
			
		|||
	}
 | 
			
		||||
	free(current_buf);
 | 
			
		||||
	current_buf = parent;
 | 
			
		||||
 | 
			
		||||
	return parent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int zconf_lineno(void)
 | 
			
		||||
{
 | 
			
		||||
	if (current_buf)
 | 
			
		||||
		return current_file->lineno - 1;
 | 
			
		||||
	else
 | 
			
		||||
		return 0;
 | 
			
		||||
	return current_pos.lineno;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *zconf_curname(void)
 | 
			
		||||
{
 | 
			
		||||
	if (current_buf)
 | 
			
		||||
		return current_file->name;
 | 
			
		||||
	else
 | 
			
		||||
		return "<none>";
 | 
			
		||||
	return current_pos.file ? current_pos.file->name : "<none>";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ void kconfig_load(void);
 | 
			
		|||
 | 
			
		||||
/* menu.c */
 | 
			
		||||
void menu_init(void);
 | 
			
		||||
void menu_add_menu(void);
 | 
			
		||||
struct menu *menu_add_menu(void);
 | 
			
		||||
void menu_end_menu(void);
 | 
			
		||||
void menu_add_entry(struct symbol *sym);
 | 
			
		||||
void menu_end_entry(void);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,10 +61,11 @@ void menu_end_entry(void)
 | 
			
		|||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void menu_add_menu(void)
 | 
			
		||||
struct menu *menu_add_menu(void)
 | 
			
		||||
{
 | 
			
		||||
	current_menu = current_entry;
 | 
			
		||||
	menu_end_entry();
 | 
			
		||||
	last_entry_ptr = ¤t_entry->list;
 | 
			
		||||
	return current_menu = current_entry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void menu_end_menu(void)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,11 @@
 | 
			
		|||
 | 
			
		||||
#define START_STRSIZE	16
 | 
			
		||||
 | 
			
		||||
static struct {
 | 
			
		||||
	struct file *file;
 | 
			
		||||
	int lineno;
 | 
			
		||||
} current_pos;
 | 
			
		||||
 | 
			
		||||
static char *text;
 | 
			
		||||
static int text_size, text_asize;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +36,7 @@ struct buffer *current_buf;
 | 
			
		|||
static int last_ts, first_ts;
 | 
			
		||||
 | 
			
		||||
static void zconf_endhelp(void);
 | 
			
		||||
static struct buffer *zconf_endfile(void);
 | 
			
		||||
static void zconf_endfile(void);
 | 
			
		||||
 | 
			
		||||
void new_string(void)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -70,10 +75,13 @@ n	[A-Za-z0-9_]
 | 
			
		|||
	int str = 0;
 | 
			
		||||
	int ts, i;
 | 
			
		||||
 | 
			
		||||
[ \t]*#.*\n	current_file->lineno++;
 | 
			
		||||
[ \t]*#.*\n	|
 | 
			
		||||
[ \t]*\n	{
 | 
			
		||||
	current_file->lineno++;
 | 
			
		||||
	return T_EOL;
 | 
			
		||||
}
 | 
			
		||||
[ \t]*#.*
 | 
			
		||||
 | 
			
		||||
[ \t]*\n	current_file->lineno++; return T_EOL;
 | 
			
		||||
 | 
			
		||||
[ \t]+	{
 | 
			
		||||
	BEGIN(COMMAND);
 | 
			
		||||
| 
						 | 
				
			
			@ -88,8 +96,10 @@ n	[A-Za-z0-9_]
 | 
			
		|||
<COMMAND>{
 | 
			
		||||
	{n}+	{
 | 
			
		||||
		struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
 | 
			
		||||
		if (id && id->flags & TF_COMMAND) {
 | 
			
		||||
		BEGIN(PARAM);
 | 
			
		||||
		current_pos.file = current_file;
 | 
			
		||||
		current_pos.lineno = current_file->lineno;
 | 
			
		||||
		if (id && id->flags & TF_COMMAND) {
 | 
			
		||||
			zconflval.id = id;
 | 
			
		||||
			return id->token;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +108,11 @@ n	[A-Za-z0-9_]
 | 
			
		|||
		return T_WORD;
 | 
			
		||||
	}
 | 
			
		||||
	.
 | 
			
		||||
	\n	current_file->lineno++; BEGIN(INITIAL);
 | 
			
		||||
	\n	{
 | 
			
		||||
		BEGIN(INITIAL);
 | 
			
		||||
		current_file->lineno++;
 | 
			
		||||
		return T_EOL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<PARAM>{
 | 
			
		||||
| 
						 | 
				
			
			@ -214,9 +228,9 @@ n	[A-Za-z0-9_]
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
<<EOF>>	{
 | 
			
		||||
	if (current_buf) {
 | 
			
		||||
	if (current_file) {
 | 
			
		||||
		zconf_endfile();
 | 
			
		||||
		return T_EOF;
 | 
			
		||||
		return T_EOL;
 | 
			
		||||
	}
 | 
			
		||||
	fclose(yyin);
 | 
			
		||||
	yyterminate();
 | 
			
		||||
| 
						 | 
				
			
			@ -307,7 +321,7 @@ void zconf_nextfile(const char *name)
 | 
			
		|||
	current_file = file;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct buffer *zconf_endfile(void)
 | 
			
		||||
static void zconf_endfile(void)
 | 
			
		||||
{
 | 
			
		||||
	struct buffer *parent;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -323,22 +337,14 @@ static struct buffer *zconf_endfile(void)
 | 
			
		|||
	}
 | 
			
		||||
	free(current_buf);
 | 
			
		||||
	current_buf = parent;
 | 
			
		||||
 | 
			
		||||
	return parent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int zconf_lineno(void)
 | 
			
		||||
{
 | 
			
		||||
	if (current_buf)
 | 
			
		||||
		return current_file->lineno - 1;
 | 
			
		||||
	else
 | 
			
		||||
		return 0;
 | 
			
		||||
	return current_pos.lineno;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *zconf_curname(void)
 | 
			
		||||
{
 | 
			
		||||
	if (current_buf)
 | 
			
		||||
		return current_file->name;
 | 
			
		||||
	else
 | 
			
		||||
		return "<none>";
 | 
			
		||||
	return current_pos.file ? current_pos.file->name : "<none>";
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -25,21 +25,25 @@ int cdebug = PRINTD;
 | 
			
		|||
 | 
			
		||||
extern int zconflex(void);
 | 
			
		||||
static void zconfprint(const char *err, ...);
 | 
			
		||||
static void zconf_error(const char *err, ...);
 | 
			
		||||
static void zconferror(const char *err);
 | 
			
		||||
static bool zconf_endtoken(int token, int starttoken, int endtoken);
 | 
			
		||||
static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
 | 
			
		||||
 | 
			
		||||
struct symbol *symbol_hash[257];
 | 
			
		||||
 | 
			
		||||
static struct menu *current_menu, *current_entry;
 | 
			
		||||
 | 
			
		||||
#define YYDEBUG 0
 | 
			
		||||
#if YYDEBUG
 | 
			
		||||
#define YYERROR_VERBOSE
 | 
			
		||||
#endif
 | 
			
		||||
%}
 | 
			
		||||
%expect 40
 | 
			
		||||
%expect 26
 | 
			
		||||
 | 
			
		||||
%union
 | 
			
		||||
{
 | 
			
		||||
	int token;
 | 
			
		||||
	char *string;
 | 
			
		||||
	struct file *file;
 | 
			
		||||
	struct symbol *symbol;
 | 
			
		||||
	struct expr *expr;
 | 
			
		||||
	struct menu *menu;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +78,6 @@ static struct menu *current_menu, *current_entry;
 | 
			
		|||
%token T_CLOSE_PAREN
 | 
			
		||||
%token T_OPEN_PAREN
 | 
			
		||||
%token T_EOL
 | 
			
		||||
%token T_EOF
 | 
			
		||||
 | 
			
		||||
%left T_OR
 | 
			
		||||
%left T_AND
 | 
			
		||||
| 
						 | 
				
			
			@ -82,34 +85,54 @@ static struct menu *current_menu, *current_entry;
 | 
			
		|||
%nonassoc T_NOT
 | 
			
		||||
 | 
			
		||||
%type <string> prompt
 | 
			
		||||
%type <string> source
 | 
			
		||||
%type <symbol> symbol
 | 
			
		||||
%type <expr> expr
 | 
			
		||||
%type <expr> if_expr
 | 
			
		||||
%type <token> end
 | 
			
		||||
%type <id> end
 | 
			
		||||
%type <id> option_name
 | 
			
		||||
%type <menu> if_entry menu_entry choice_entry
 | 
			
		||||
 | 
			
		||||
%destructor {
 | 
			
		||||
	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
 | 
			
		||||
		$$->file->name, $$->lineno);
 | 
			
		||||
	if (current_menu == $$)
 | 
			
		||||
		menu_end_menu();
 | 
			
		||||
} if_entry menu_entry choice_entry
 | 
			
		||||
 | 
			
		||||
%%
 | 
			
		||||
input:	  /* empty */
 | 
			
		||||
	| input block
 | 
			
		||||
input: stmt_list;
 | 
			
		||||
 | 
			
		||||
stmt_list:
 | 
			
		||||
	  /* empty */
 | 
			
		||||
	| stmt_list common_stmt
 | 
			
		||||
	| stmt_list choice_stmt
 | 
			
		||||
	| stmt_list menu_stmt
 | 
			
		||||
	| stmt_list T_MAINMENU prompt nl
 | 
			
		||||
	| stmt_list end			{ zconf_error("unexpected end statement"); }
 | 
			
		||||
	| stmt_list T_WORD error T_EOL	{ zconf_error("unknown statement \"%s\"", $2); }
 | 
			
		||||
	| stmt_list option_name error T_EOL
 | 
			
		||||
{
 | 
			
		||||
	zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
 | 
			
		||||
}
 | 
			
		||||
	| stmt_list error T_EOL		{ zconf_error("invalid statement"); }
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
block:	  common_block
 | 
			
		||||
	| choice_stmt
 | 
			
		||||
	| menu_stmt
 | 
			
		||||
	| T_MAINMENU prompt nl_or_eof
 | 
			
		||||
	| T_ENDMENU		{ zconfprint("unexpected 'endmenu' statement"); }
 | 
			
		||||
	| T_ENDIF		{ zconfprint("unexpected 'endif' statement"); }
 | 
			
		||||
	| T_ENDCHOICE		{ zconfprint("unexpected 'endchoice' statement"); }
 | 
			
		||||
	| error nl_or_eof	{ zconfprint("syntax error"); yyerrok; }
 | 
			
		||||
option_name:
 | 
			
		||||
	T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
common_block:
 | 
			
		||||
	  if_stmt
 | 
			
		||||
common_stmt:
 | 
			
		||||
	  T_EOL
 | 
			
		||||
	| if_stmt
 | 
			
		||||
	| comment_stmt
 | 
			
		||||
	| config_stmt
 | 
			
		||||
	| menuconfig_stmt
 | 
			
		||||
	| source_stmt
 | 
			
		||||
	| nl_or_eof
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
option_error:
 | 
			
		||||
	  T_WORD error T_EOL		{ zconf_error("unknown option \"%s\"", $1); }
 | 
			
		||||
	| error T_EOL			{ zconf_error("invalid option"); }
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -152,6 +175,7 @@ config_option_list:
 | 
			
		|||
	| config_option_list config_option
 | 
			
		||||
	| config_option_list depends
 | 
			
		||||
	| config_option_list help
 | 
			
		||||
	| config_option_list option_error
 | 
			
		||||
	| config_option_list T_EOL
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -204,8 +228,7 @@ choice: T_CHOICE T_EOL
 | 
			
		|||
 | 
			
		||||
choice_entry: choice choice_option_list
 | 
			
		||||
{
 | 
			
		||||
	menu_end_entry();
 | 
			
		||||
	menu_add_menu();
 | 
			
		||||
	$$ = menu_add_menu();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
choice_end: end
 | 
			
		||||
| 
						 | 
				
			
			@ -216,13 +239,8 @@ choice_end: end
 | 
			
		|||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
choice_stmt:
 | 
			
		||||
	  choice_entry choice_block choice_end
 | 
			
		||||
	| choice_entry choice_block
 | 
			
		||||
{
 | 
			
		||||
	printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
 | 
			
		||||
	zconfnerrs++;
 | 
			
		||||
};
 | 
			
		||||
choice_stmt: choice_entry choice_block choice_end
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
choice_option_list:
 | 
			
		||||
	  /* empty */
 | 
			
		||||
| 
						 | 
				
			
			@ -230,6 +248,7 @@ choice_option_list:
 | 
			
		|||
	| choice_option_list depends
 | 
			
		||||
	| choice_option_list help
 | 
			
		||||
	| choice_option_list T_EOL
 | 
			
		||||
	| choice_option_list option_error
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
choice_option: T_PROMPT prompt if_expr T_EOL
 | 
			
		||||
| 
						 | 
				
			
			@ -267,18 +286,17 @@ choice_option: T_DEFAULT T_WORD if_expr T_EOL
 | 
			
		|||
 | 
			
		||||
choice_block:
 | 
			
		||||
	  /* empty */
 | 
			
		||||
	| choice_block common_block
 | 
			
		||||
	| choice_block common_stmt
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
/* if entry */
 | 
			
		||||
 | 
			
		||||
if: T_IF expr T_EOL
 | 
			
		||||
if_entry: T_IF expr nl
 | 
			
		||||
{
 | 
			
		||||
	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
 | 
			
		||||
	menu_add_entry(NULL);
 | 
			
		||||
	menu_add_dep($2);
 | 
			
		||||
	menu_end_entry();
 | 
			
		||||
	menu_add_menu();
 | 
			
		||||
	$$ = menu_add_menu();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
if_end: end
 | 
			
		||||
| 
						 | 
				
			
			@ -289,17 +307,12 @@ if_end: end
 | 
			
		|||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
if_stmt:
 | 
			
		||||
	  if if_block if_end
 | 
			
		||||
	| if if_block
 | 
			
		||||
{
 | 
			
		||||
	printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
 | 
			
		||||
	zconfnerrs++;
 | 
			
		||||
};
 | 
			
		||||
if_stmt: if_entry if_block if_end
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
if_block:
 | 
			
		||||
	  /* empty */
 | 
			
		||||
	| if_block common_block
 | 
			
		||||
	| if_block common_stmt
 | 
			
		||||
	| if_block menu_stmt
 | 
			
		||||
	| if_block choice_stmt
 | 
			
		||||
;
 | 
			
		||||
| 
						 | 
				
			
			@ -315,8 +328,7 @@ menu: T_MENU prompt T_EOL
 | 
			
		|||
 | 
			
		||||
menu_entry: menu depends_list
 | 
			
		||||
{
 | 
			
		||||
	menu_end_entry();
 | 
			
		||||
	menu_add_menu();
 | 
			
		||||
	$$ = menu_add_menu();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
menu_end: end
 | 
			
		||||
| 
						 | 
				
			
			@ -327,31 +339,20 @@ menu_end: end
 | 
			
		|||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
menu_stmt:
 | 
			
		||||
	  menu_entry menu_block menu_end
 | 
			
		||||
	| menu_entry menu_block
 | 
			
		||||
{
 | 
			
		||||
	printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
 | 
			
		||||
	zconfnerrs++;
 | 
			
		||||
};
 | 
			
		||||
menu_stmt: menu_entry menu_block menu_end
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
menu_block:
 | 
			
		||||
	  /* empty */
 | 
			
		||||
	| menu_block common_block
 | 
			
		||||
	| menu_block common_stmt
 | 
			
		||||
	| menu_block menu_stmt
 | 
			
		||||
	| menu_block choice_stmt
 | 
			
		||||
	| menu_block error T_EOL		{ zconfprint("invalid menu option"); yyerrok; }
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
source: T_SOURCE prompt T_EOL
 | 
			
		||||
source_stmt: T_SOURCE prompt T_EOL
 | 
			
		||||
{
 | 
			
		||||
	$$ = $2;
 | 
			
		||||
	printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
source_stmt: source
 | 
			
		||||
{
 | 
			
		||||
	zconf_nextfile($1);
 | 
			
		||||
	zconf_nextfile($2);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* comment entry */
 | 
			
		||||
| 
						 | 
				
			
			@ -383,9 +384,11 @@ help: help_start T_HELPTEXT
 | 
			
		|||
 | 
			
		||||
/* depends option */
 | 
			
		||||
 | 
			
		||||
depends_list:	  /* empty */
 | 
			
		||||
depends_list:
 | 
			
		||||
	  /* empty */
 | 
			
		||||
	| depends_list depends
 | 
			
		||||
	| depends_list T_EOL
 | 
			
		||||
	| depends_list option_error
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
depends: T_DEPENDS T_ON expr T_EOL
 | 
			
		||||
| 
						 | 
				
			
			@ -417,13 +420,15 @@ prompt:	  T_WORD
 | 
			
		|||
	| T_WORD_QUOTE
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
end:	  T_ENDMENU nl_or_eof	{ $$ = T_ENDMENU; }
 | 
			
		||||
	| T_ENDCHOICE nl_or_eof	{ $$ = T_ENDCHOICE; }
 | 
			
		||||
	| T_ENDIF nl_or_eof	{ $$ = T_ENDIF; }
 | 
			
		||||
end:	  T_ENDMENU T_EOL	{ $$ = $1; }
 | 
			
		||||
	| T_ENDCHOICE T_EOL	{ $$ = $1; }
 | 
			
		||||
	| T_ENDIF T_EOL		{ $$ = $1; }
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
nl_or_eof:
 | 
			
		||||
	T_EOL | T_EOF;
 | 
			
		||||
nl:
 | 
			
		||||
	  T_EOL
 | 
			
		||||
	| nl T_EOL
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
if_expr:  /* empty */			{ $$ = NULL; }
 | 
			
		||||
	| T_IF expr			{ $$ = $2; }
 | 
			
		||||
| 
						 | 
				
			
			@ -456,7 +461,10 @@ void conf_parse(const char *name)
 | 
			
		|||
	modules_sym = sym_lookup("MODULES", 0);
 | 
			
		||||
	rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
 | 
			
		||||
 | 
			
		||||
	//zconfdebug = 1;
 | 
			
		||||
#if YYDEBUG
 | 
			
		||||
	if (getenv("ZCONF_DEBUG"))
 | 
			
		||||
		zconfdebug = 1;
 | 
			
		||||
#endif
 | 
			
		||||
	zconfparse();
 | 
			
		||||
	if (zconfnerrs)
 | 
			
		||||
		exit(1);
 | 
			
		||||
| 
						 | 
				
			
			@ -477,20 +485,25 @@ const char *zconf_tokenname(int token)
 | 
			
		|||
	case T_ENDCHOICE:	return "endchoice";
 | 
			
		||||
	case T_IF:		return "if";
 | 
			
		||||
	case T_ENDIF:		return "endif";
 | 
			
		||||
	case T_DEPENDS:		return "depends";
 | 
			
		||||
	}
 | 
			
		||||
	return "<token>";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool zconf_endtoken(int token, int starttoken, int endtoken)
 | 
			
		||||
static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
 | 
			
		||||
{
 | 
			
		||||
	if (token != endtoken) {
 | 
			
		||||
		zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
 | 
			
		||||
	if (id->token != endtoken) {
 | 
			
		||||
		zconf_error("unexpected '%s' within %s block",
 | 
			
		||||
			kconf_id_strings + id->name, zconf_tokenname(starttoken));
 | 
			
		||||
		zconfnerrs++;
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	if (current_menu->file != current_file) {
 | 
			
		||||
		zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
 | 
			
		||||
		zconfprint("location of the '%s'", zconf_tokenname(starttoken));
 | 
			
		||||
		zconf_error("'%s' in different file than '%s'",
 | 
			
		||||
			kconf_id_strings + id->name, zconf_tokenname(starttoken));
 | 
			
		||||
		fprintf(stderr, "%s:%d: location of the '%s'\n",
 | 
			
		||||
			current_menu->file->name, current_menu->lineno,
 | 
			
		||||
			zconf_tokenname(starttoken));
 | 
			
		||||
		zconfnerrs++;
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -501,7 +514,19 @@ static void zconfprint(const char *err, ...)
 | 
			
		|||
{
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
 | 
			
		||||
	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
 | 
			
		||||
	va_start(ap, err);
 | 
			
		||||
	vfprintf(stderr, err, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
	fprintf(stderr, "\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void zconf_error(const char *err, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	zconfnerrs++;
 | 
			
		||||
	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
 | 
			
		||||
	va_start(ap, err);
 | 
			
		||||
	vfprintf(stderr, err, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
| 
						 | 
				
			
			@ -510,7 +535,9 @@ static void zconfprint(const char *err, ...)
 | 
			
		|||
 | 
			
		||||
static void zconferror(const char *err)
 | 
			
		||||
{
 | 
			
		||||
#if YYDEBUG
 | 
			
		||||
	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_quoted_string(FILE *out, const char *str)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue