[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:
Родитель
3370f9f0d9
Коммит
a02f0570ae
|
@ -323,7 +323,7 @@ void zconffree (void * );
|
||||||
|
|
||||||
/* Begin user sect3 */
|
/* Begin user sect3 */
|
||||||
|
|
||||||
#define zconfwrap(n) 1
|
#define zconfwrap() 1
|
||||||
#define YY_SKIP_YYWRAP
|
#define YY_SKIP_YYWRAP
|
||||||
|
|
||||||
typedef unsigned char YY_CHAR;
|
typedef unsigned char YY_CHAR;
|
||||||
|
@ -686,10 +686,10 @@ struct yy_trans_info
|
||||||
static yyconst flex_int16_t yy_accept[61] =
|
static yyconst flex_int16_t yy_accept[61] =
|
||||||
{ 0,
|
{ 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
|
31, 24, 28, 27, 26, 22, 17, 13, 16, 20,
|
||||||
22, 11, 12, 19, 19, 14, 22, 22, 4, 3,
|
22, 11, 12, 19, 19, 14, 22, 22, 4, 2,
|
||||||
2, 2, 1, 6, 32, 29, 31, 30, 24, 23,
|
3, 3, 1, 6, 32, 29, 31, 30, 24, 23,
|
||||||
26, 25, 15, 20, 9, 19, 19, 21, 10, 18
|
26, 25, 15, 20, 9, 19, 19, 21, 10, 18
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -753,6 +753,11 @@ char *zconftext;
|
||||||
|
|
||||||
#define START_STRSIZE 16
|
#define START_STRSIZE 16
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
struct file *file;
|
||||||
|
int lineno;
|
||||||
|
} current_pos;
|
||||||
|
|
||||||
static char *text;
|
static char *text;
|
||||||
static int text_size, text_asize;
|
static int text_size, text_asize;
|
||||||
|
|
||||||
|
@ -766,7 +771,7 @@ struct buffer *current_buf;
|
||||||
static int last_ts, first_ts;
|
static int last_ts, first_ts;
|
||||||
|
|
||||||
static void zconf_endhelp(void);
|
static void zconf_endhelp(void);
|
||||||
static struct buffer *zconf_endfile(void);
|
static void zconf_endfile(void);
|
||||||
|
|
||||||
void new_string(void)
|
void new_string(void)
|
||||||
{
|
{
|
||||||
|
@ -993,17 +998,17 @@ do_action: /* This label is used only to access EOF actions. */
|
||||||
{ /* beginning of action switch */
|
{ /* beginning of action switch */
|
||||||
case 1:
|
case 1:
|
||||||
/* rule 1 can match eol */
|
/* rule 1 can match eol */
|
||||||
YY_RULE_SETUP
|
|
||||||
current_file->lineno++;
|
|
||||||
YY_BREAK
|
|
||||||
case 2:
|
case 2:
|
||||||
|
/* rule 2 can match eol */
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
|
{
|
||||||
|
current_file->lineno++;
|
||||||
|
return T_EOL;
|
||||||
|
}
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 3:
|
case 3:
|
||||||
/* rule 3 can match eol */
|
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
current_file->lineno++; return T_EOL;
|
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 4:
|
case 4:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
|
@ -1023,8 +1028,10 @@ case 6:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
{
|
{
|
||||||
struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
|
struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
|
||||||
|
BEGIN(PARAM);
|
||||||
|
current_pos.file = current_file;
|
||||||
|
current_pos.lineno = current_file->lineno;
|
||||||
if (id && id->flags & TF_COMMAND) {
|
if (id && id->flags & TF_COMMAND) {
|
||||||
BEGIN(PARAM);
|
|
||||||
zconflval.id = id;
|
zconflval.id = id;
|
||||||
return id->token;
|
return id->token;
|
||||||
}
|
}
|
||||||
|
@ -1040,7 +1047,11 @@ YY_RULE_SETUP
|
||||||
case 8:
|
case 8:
|
||||||
/* rule 8 can match eol */
|
/* rule 8 can match eol */
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
current_file->lineno++; BEGIN(INITIAL);
|
{
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
current_file->lineno++;
|
||||||
|
return T_EOL;
|
||||||
|
}
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
|
@ -1246,9 +1257,9 @@ case YY_STATE_EOF(HELP):
|
||||||
case YY_STATE_EOF(INITIAL):
|
case YY_STATE_EOF(INITIAL):
|
||||||
case YY_STATE_EOF(COMMAND):
|
case YY_STATE_EOF(COMMAND):
|
||||||
{
|
{
|
||||||
if (current_buf) {
|
if (current_file) {
|
||||||
zconf_endfile();
|
zconf_endfile();
|
||||||
return T_EOF;
|
return T_EOL;
|
||||||
}
|
}
|
||||||
fclose(zconfin);
|
fclose(zconfin);
|
||||||
yyterminate();
|
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
|
/** Setup the input buffer state to scan a string. The next call to zconflex() will
|
||||||
* scan from a @e copy of @a str.
|
* 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.
|
* @return the newly allocated buffer state object.
|
||||||
* @note If you want to scan bytes that may contain NUL values, then use
|
* @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;
|
current_file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct buffer *zconf_endfile(void)
|
static void zconf_endfile(void)
|
||||||
{
|
{
|
||||||
struct buffer *parent;
|
struct buffer *parent;
|
||||||
|
|
||||||
|
@ -2292,23 +2303,15 @@ static struct buffer *zconf_endfile(void)
|
||||||
}
|
}
|
||||||
free(current_buf);
|
free(current_buf);
|
||||||
current_buf = parent;
|
current_buf = parent;
|
||||||
|
|
||||||
return parent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int zconf_lineno(void)
|
int zconf_lineno(void)
|
||||||
{
|
{
|
||||||
if (current_buf)
|
return current_pos.lineno;
|
||||||
return current_file->lineno - 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *zconf_curname(void)
|
char *zconf_curname(void)
|
||||||
{
|
{
|
||||||
if (current_buf)
|
return current_pos.file ? current_pos.file->name : "<none>";
|
||||||
return current_file->name;
|
|
||||||
else
|
|
||||||
return "<none>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ void kconfig_load(void);
|
||||||
|
|
||||||
/* menu.c */
|
/* menu.c */
|
||||||
void menu_init(void);
|
void menu_init(void);
|
||||||
void menu_add_menu(void);
|
struct menu *menu_add_menu(void);
|
||||||
void menu_end_menu(void);
|
void menu_end_menu(void);
|
||||||
void menu_add_entry(struct symbol *sym);
|
void menu_add_entry(struct symbol *sym);
|
||||||
void menu_end_entry(void);
|
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;
|
last_entry_ptr = ¤t_entry->list;
|
||||||
|
return current_menu = current_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_end_menu(void)
|
void menu_end_menu(void)
|
||||||
|
|
|
@ -18,6 +18,11 @@
|
||||||
|
|
||||||
#define START_STRSIZE 16
|
#define START_STRSIZE 16
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
struct file *file;
|
||||||
|
int lineno;
|
||||||
|
} current_pos;
|
||||||
|
|
||||||
static char *text;
|
static char *text;
|
||||||
static int text_size, text_asize;
|
static int text_size, text_asize;
|
||||||
|
|
||||||
|
@ -31,7 +36,7 @@ struct buffer *current_buf;
|
||||||
static int last_ts, first_ts;
|
static int last_ts, first_ts;
|
||||||
|
|
||||||
static void zconf_endhelp(void);
|
static void zconf_endhelp(void);
|
||||||
static struct buffer *zconf_endfile(void);
|
static void zconf_endfile(void);
|
||||||
|
|
||||||
void new_string(void)
|
void new_string(void)
|
||||||
{
|
{
|
||||||
|
@ -70,10 +75,13 @@ n [A-Za-z0-9_]
|
||||||
int str = 0;
|
int str = 0;
|
||||||
int ts, i;
|
int ts, i;
|
||||||
|
|
||||||
[ \t]*#.*\n current_file->lineno++;
|
[ \t]*#.*\n |
|
||||||
|
[ \t]*\n {
|
||||||
|
current_file->lineno++;
|
||||||
|
return T_EOL;
|
||||||
|
}
|
||||||
[ \t]*#.*
|
[ \t]*#.*
|
||||||
|
|
||||||
[ \t]*\n current_file->lineno++; return T_EOL;
|
|
||||||
|
|
||||||
[ \t]+ {
|
[ \t]+ {
|
||||||
BEGIN(COMMAND);
|
BEGIN(COMMAND);
|
||||||
|
@ -88,8 +96,10 @@ n [A-Za-z0-9_]
|
||||||
<COMMAND>{
|
<COMMAND>{
|
||||||
{n}+ {
|
{n}+ {
|
||||||
struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
|
struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
|
||||||
|
BEGIN(PARAM);
|
||||||
|
current_pos.file = current_file;
|
||||||
|
current_pos.lineno = current_file->lineno;
|
||||||
if (id && id->flags & TF_COMMAND) {
|
if (id && id->flags & TF_COMMAND) {
|
||||||
BEGIN(PARAM);
|
|
||||||
zconflval.id = id;
|
zconflval.id = id;
|
||||||
return id->token;
|
return id->token;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +108,11 @@ n [A-Za-z0-9_]
|
||||||
return T_WORD;
|
return T_WORD;
|
||||||
}
|
}
|
||||||
.
|
.
|
||||||
\n current_file->lineno++; BEGIN(INITIAL);
|
\n {
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
current_file->lineno++;
|
||||||
|
return T_EOL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<PARAM>{
|
<PARAM>{
|
||||||
|
@ -214,9 +228,9 @@ n [A-Za-z0-9_]
|
||||||
}
|
}
|
||||||
|
|
||||||
<<EOF>> {
|
<<EOF>> {
|
||||||
if (current_buf) {
|
if (current_file) {
|
||||||
zconf_endfile();
|
zconf_endfile();
|
||||||
return T_EOF;
|
return T_EOL;
|
||||||
}
|
}
|
||||||
fclose(yyin);
|
fclose(yyin);
|
||||||
yyterminate();
|
yyterminate();
|
||||||
|
@ -307,7 +321,7 @@ void zconf_nextfile(const char *name)
|
||||||
current_file = file;
|
current_file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct buffer *zconf_endfile(void)
|
static void zconf_endfile(void)
|
||||||
{
|
{
|
||||||
struct buffer *parent;
|
struct buffer *parent;
|
||||||
|
|
||||||
|
@ -323,22 +337,14 @@ static struct buffer *zconf_endfile(void)
|
||||||
}
|
}
|
||||||
free(current_buf);
|
free(current_buf);
|
||||||
current_buf = parent;
|
current_buf = parent;
|
||||||
|
|
||||||
return parent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int zconf_lineno(void)
|
int zconf_lineno(void)
|
||||||
{
|
{
|
||||||
if (current_buf)
|
return current_pos.lineno;
|
||||||
return current_file->lineno - 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *zconf_curname(void)
|
char *zconf_curname(void)
|
||||||
{
|
{
|
||||||
if (current_buf)
|
return current_pos.file ? current_pos.file->name : "<none>";
|
||||||
return current_file->name;
|
|
||||||
else
|
|
||||||
return "<none>";
|
|
||||||
}
|
}
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -25,21 +25,25 @@ int cdebug = PRINTD;
|
||||||
|
|
||||||
extern int zconflex(void);
|
extern int zconflex(void);
|
||||||
static void zconfprint(const char *err, ...);
|
static void zconfprint(const char *err, ...);
|
||||||
|
static void zconf_error(const char *err, ...);
|
||||||
static void zconferror(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];
|
struct symbol *symbol_hash[257];
|
||||||
|
|
||||||
static struct menu *current_menu, *current_entry;
|
static struct menu *current_menu, *current_entry;
|
||||||
|
|
||||||
|
#define YYDEBUG 0
|
||||||
|
#if YYDEBUG
|
||||||
#define YYERROR_VERBOSE
|
#define YYERROR_VERBOSE
|
||||||
|
#endif
|
||||||
%}
|
%}
|
||||||
%expect 40
|
%expect 26
|
||||||
|
|
||||||
%union
|
%union
|
||||||
{
|
{
|
||||||
int token;
|
|
||||||
char *string;
|
char *string;
|
||||||
|
struct file *file;
|
||||||
struct symbol *symbol;
|
struct symbol *symbol;
|
||||||
struct expr *expr;
|
struct expr *expr;
|
||||||
struct menu *menu;
|
struct menu *menu;
|
||||||
|
@ -74,7 +78,6 @@ static struct menu *current_menu, *current_entry;
|
||||||
%token T_CLOSE_PAREN
|
%token T_CLOSE_PAREN
|
||||||
%token T_OPEN_PAREN
|
%token T_OPEN_PAREN
|
||||||
%token T_EOL
|
%token T_EOL
|
||||||
%token T_EOF
|
|
||||||
|
|
||||||
%left T_OR
|
%left T_OR
|
||||||
%left T_AND
|
%left T_AND
|
||||||
|
@ -82,34 +85,54 @@ static struct menu *current_menu, *current_entry;
|
||||||
%nonassoc T_NOT
|
%nonassoc T_NOT
|
||||||
|
|
||||||
%type <string> prompt
|
%type <string> prompt
|
||||||
%type <string> source
|
|
||||||
%type <symbol> symbol
|
%type <symbol> symbol
|
||||||
%type <expr> expr
|
%type <expr> expr
|
||||||
%type <expr> if_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: stmt_list;
|
||||||
| input block
|
|
||||||
|
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
|
option_name:
|
||||||
| choice_stmt
|
T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
|
||||||
| 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; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
common_block:
|
common_stmt:
|
||||||
if_stmt
|
T_EOL
|
||||||
|
| if_stmt
|
||||||
| comment_stmt
|
| comment_stmt
|
||||||
| config_stmt
|
| config_stmt
|
||||||
| menuconfig_stmt
|
| menuconfig_stmt
|
||||||
| source_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 config_option
|
||||||
| config_option_list depends
|
| config_option_list depends
|
||||||
| config_option_list help
|
| config_option_list help
|
||||||
|
| config_option_list option_error
|
||||||
| config_option_list T_EOL
|
| config_option_list T_EOL
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -204,8 +228,7 @@ choice: T_CHOICE T_EOL
|
||||||
|
|
||||||
choice_entry: choice choice_option_list
|
choice_entry: choice choice_option_list
|
||||||
{
|
{
|
||||||
menu_end_entry();
|
$$ = menu_add_menu();
|
||||||
menu_add_menu();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
choice_end: end
|
choice_end: end
|
||||||
|
@ -216,13 +239,8 @@ choice_end: end
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
choice_stmt:
|
choice_stmt: choice_entry choice_block choice_end
|
||||||
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_option_list:
|
choice_option_list:
|
||||||
/* empty */
|
/* empty */
|
||||||
|
@ -230,6 +248,7 @@ choice_option_list:
|
||||||
| choice_option_list depends
|
| choice_option_list depends
|
||||||
| choice_option_list help
|
| choice_option_list help
|
||||||
| choice_option_list T_EOL
|
| choice_option_list T_EOL
|
||||||
|
| choice_option_list option_error
|
||||||
;
|
;
|
||||||
|
|
||||||
choice_option: T_PROMPT prompt if_expr T_EOL
|
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:
|
choice_block:
|
||||||
/* empty */
|
/* empty */
|
||||||
| choice_block common_block
|
| choice_block common_stmt
|
||||||
;
|
;
|
||||||
|
|
||||||
/* if entry */
|
/* 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());
|
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
|
||||||
menu_add_entry(NULL);
|
menu_add_entry(NULL);
|
||||||
menu_add_dep($2);
|
menu_add_dep($2);
|
||||||
menu_end_entry();
|
$$ = menu_add_menu();
|
||||||
menu_add_menu();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if_end: end
|
if_end: end
|
||||||
|
@ -289,17 +307,12 @@ if_end: end
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if_stmt:
|
if_stmt: if_entry if_block if_end
|
||||||
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_block:
|
if_block:
|
||||||
/* empty */
|
/* empty */
|
||||||
| if_block common_block
|
| if_block common_stmt
|
||||||
| if_block menu_stmt
|
| if_block menu_stmt
|
||||||
| if_block choice_stmt
|
| if_block choice_stmt
|
||||||
;
|
;
|
||||||
|
@ -315,8 +328,7 @@ menu: T_MENU prompt T_EOL
|
||||||
|
|
||||||
menu_entry: menu depends_list
|
menu_entry: menu depends_list
|
||||||
{
|
{
|
||||||
menu_end_entry();
|
$$ = menu_add_menu();
|
||||||
menu_add_menu();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_end: end
|
menu_end: end
|
||||||
|
@ -327,31 +339,20 @@ menu_end: end
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_stmt:
|
menu_stmt: menu_entry menu_block menu_end
|
||||||
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_block:
|
menu_block:
|
||||||
/* empty */
|
/* empty */
|
||||||
| menu_block common_block
|
| menu_block common_stmt
|
||||||
| menu_block menu_stmt
|
| menu_block menu_stmt
|
||||||
| menu_block choice_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);
|
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
|
||||||
};
|
zconf_nextfile($2);
|
||||||
|
|
||||||
source_stmt: source
|
|
||||||
{
|
|
||||||
zconf_nextfile($1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* comment entry */
|
/* comment entry */
|
||||||
|
@ -383,9 +384,11 @@ help: help_start T_HELPTEXT
|
||||||
|
|
||||||
/* depends option */
|
/* depends option */
|
||||||
|
|
||||||
depends_list: /* empty */
|
depends_list:
|
||||||
| depends_list depends
|
/* empty */
|
||||||
| depends_list T_EOL
|
| depends_list depends
|
||||||
|
| depends_list T_EOL
|
||||||
|
| depends_list option_error
|
||||||
;
|
;
|
||||||
|
|
||||||
depends: T_DEPENDS T_ON expr T_EOL
|
depends: T_DEPENDS T_ON expr T_EOL
|
||||||
|
@ -417,13 +420,15 @@ prompt: T_WORD
|
||||||
| T_WORD_QUOTE
|
| T_WORD_QUOTE
|
||||||
;
|
;
|
||||||
|
|
||||||
end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; }
|
end: T_ENDMENU T_EOL { $$ = $1; }
|
||||||
| T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; }
|
| T_ENDCHOICE T_EOL { $$ = $1; }
|
||||||
| T_ENDIF nl_or_eof { $$ = T_ENDIF; }
|
| T_ENDIF T_EOL { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
nl_or_eof:
|
nl:
|
||||||
T_EOL | T_EOF;
|
T_EOL
|
||||||
|
| nl T_EOL
|
||||||
|
;
|
||||||
|
|
||||||
if_expr: /* empty */ { $$ = NULL; }
|
if_expr: /* empty */ { $$ = NULL; }
|
||||||
| T_IF expr { $$ = $2; }
|
| T_IF expr { $$ = $2; }
|
||||||
|
@ -456,7 +461,10 @@ void conf_parse(const char *name)
|
||||||
modules_sym = sym_lookup("MODULES", 0);
|
modules_sym = sym_lookup("MODULES", 0);
|
||||||
rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
|
rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
|
||||||
|
|
||||||
//zconfdebug = 1;
|
#if YYDEBUG
|
||||||
|
if (getenv("ZCONF_DEBUG"))
|
||||||
|
zconfdebug = 1;
|
||||||
|
#endif
|
||||||
zconfparse();
|
zconfparse();
|
||||||
if (zconfnerrs)
|
if (zconfnerrs)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -477,20 +485,25 @@ const char *zconf_tokenname(int token)
|
||||||
case T_ENDCHOICE: return "endchoice";
|
case T_ENDCHOICE: return "endchoice";
|
||||||
case T_IF: return "if";
|
case T_IF: return "if";
|
||||||
case T_ENDIF: return "endif";
|
case T_ENDIF: return "endif";
|
||||||
|
case T_DEPENDS: return "depends";
|
||||||
}
|
}
|
||||||
return "<token>";
|
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) {
|
if (id->token != endtoken) {
|
||||||
zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
|
zconf_error("unexpected '%s' within %s block",
|
||||||
|
kconf_id_strings + id->name, zconf_tokenname(starttoken));
|
||||||
zconfnerrs++;
|
zconfnerrs++;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (current_menu->file != current_file) {
|
if (current_menu->file != current_file) {
|
||||||
zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
|
zconf_error("'%s' in different file than '%s'",
|
||||||
zconfprint("location of the '%s'", zconf_tokenname(starttoken));
|
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++;
|
zconfnerrs++;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -501,7 +514,19 @@ static void zconfprint(const char *err, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
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);
|
va_start(ap, err);
|
||||||
vfprintf(stderr, err, ap);
|
vfprintf(stderr, err, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
@ -510,7 +535,9 @@ static void zconfprint(const char *err, ...)
|
||||||
|
|
||||||
static void zconferror(const char *err)
|
static void zconferror(const char *err)
|
||||||
{
|
{
|
||||||
|
#if YYDEBUG
|
||||||
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
|
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_quoted_string(FILE *out, const char *str)
|
void print_quoted_string(FILE *out, const char *str)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче