From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/parser.h | 2 +- tools/widl/parser.l | 77 ++++++++++++++++++++++++++++++++----------- tools/widl/parser.y | 14 +++++--- tools/widl/typetree.c | 4 +-- 4 files changed, 70 insertions(+), 27 deletions(-)
diff --git a/tools/widl/parser.h b/tools/widl/parser.h index 2d35a2dd279..8dfde433334 100644 --- a/tools/widl/parser.h +++ b/tools/widl/parser.h @@ -27,7 +27,7 @@ int parser_parse(void);
extern void generic_msg( const struct location *where, const char *s, const char *t, va_list ap ); extern void parser_error( const struct location *where, const char *message ); -extern void init_location( struct location *where ); +extern void init_location( struct location *copy, const struct location *begin, const struct location *end );
extern FILE *parser_in; extern int parser_debug; diff --git a/tools/widl/parser.l b/tools/widl/parser.l index cce4fefbe61..96772cd032f 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -60,6 +60,13 @@ uuid {hd}{8}-{hd}{4}-{hd}{4}-{hd}{4}-{hd}{12}
#include "parser.tab.h"
+static void reset_location( struct location *where, const char *input_name ); +static void update_location( struct location *where, const char *yytext ); +static void end_of_line( struct location *where ); + +#define YY_USER_INIT reset_location( yylloc, input_name ) +#define YY_USER_ACTION update_location( yylloc, yytext ); + static void switch_to_acf(void);
static warning_list_t *disabled_warnings = NULL; @@ -68,7 +75,7 @@ struct import_state { YY_BUFFER_STATE buffer; char *input_name; - int line_number; + struct location where; struct list entry; }; static struct list import_stack = LIST_INIT( import_stack ); @@ -80,7 +87,7 @@ struct import struct list entry; }; static struct list imports = LIST_INIT( imports ); -static int line_number = 1; +static struct location previous_location;
/* converts an integer in string form to an unsigned long and prints an error * on overflow */ @@ -183,25 +190,28 @@ static void winrt_enable( int ns_prefix ) <PP_PRAGMA>{ midl_echo/"(" { yy_pop_state(); + yylloc->first_line -= 1; return tCPPQUOTE; } winrt{ws}+ns_prefix[^\n]* { yy_pop_state(); + yylloc->first_line -= 1; winrt_enable( TRUE ); } winrt[^\n]* { yy_pop_state(); + yylloc->first_line -= 1; winrt_enable( FALSE ); } [^\n]* { yy_pop_state(); + yylloc->first_line -= 1; return token_str( aPRAGMA, yytext, yylval ); } } <PP_LINE>[0-9]+{ws}* { yylloc->first_line = strtoul( yytext, NULL, 10 ) - 1; yylloc->last_line = yylloc->first_line; - line_number = yylloc->first_line; yy_pop_state(); yy_push_state(PP_FILE); } @@ -424,7 +434,7 @@ SAFEARRAY{ws}*/( return tSAFEARRAY; "(\.|[^"\])*" { return token_str( aSTRING, yytext, yylval ); } '(\.|[^'\])*' { return token_str( aSQSTRING, yytext, yylval ); }
- \n { line_number++; } + \n { end_of_line( yylloc ); } {ws} {} << { return SHL; } >> { return SHR; } @@ -451,7 +461,7 @@ SAFEARRAY{ws}*/( return tSAFEARRAY; } %%
-void pop_import(void) +void pop_import( struct location *where ) { struct list *entry = list_head( &import_stack ); struct import_state *state; @@ -466,11 +476,11 @@ void pop_import(void) yy_switch_to_buffer( state->buffer );
input_name = state->input_name; - line_number = state->line_number; + *where = state->where; free( state ); }
-void push_import( char *import_name ) +void push_import( const char *import_name, struct location *where ) { struct import_state *state; struct import *import; @@ -482,7 +492,7 @@ void push_import( char *import_name )
state->buffer = YY_CURRENT_BUFFER; state->input_name = input_name; - state->line_number = line_number; + state->where = *where; input_name = NULL;
/* reset buffer for <<EOF>>, in case import fails or already imported */ @@ -497,7 +507,7 @@ void push_import( char *import_name )
input_name = find_input_file( import_name, state->input_name ); file = open_input_file( input_name ); - line_number = 1; + reset_location( where, input_name );
yy_switch_to_buffer( yy_create_buffer( file, YY_BUF_SIZE ) ); } @@ -511,13 +521,35 @@ static void switch_to_acf(void)
input_name = xstrdup( acf_name ); file = open_input_file( input_name ); - line_number = 1; acf_name = NULL;
yy_switch_to_buffer( yy_create_buffer( file, YY_BUF_SIZE ) ); }
-#define CURRENT_LOCATION { input_name ? input_name : "stdin", parser_text, line_number, 0, line_number, 0 } +static void reset_location( struct location *where, const char *input_name ) +{ + where->first_line = 1; + where->last_line = 1; + where->first_column = 1; + where->last_column = 1; + where->input_name = xstrdup( input_name ); +} + +static void update_location( struct location *where, const char *yytext ) +{ + int len = strlen( yytext ); + previous_location = *where; + where->first_column = where->last_column; + where->last_column += len; +} + +static void end_of_line( struct location *where ) +{ + where->first_line++; + where->last_line++; + where->first_column = 1; + where->last_column = 1; +}
static const int want_near_indication = 0;
@@ -531,19 +563,26 @@ static void make_print(char *str) } }
-void init_location( struct location *where ) +void init_location( struct location *where, const struct location *begin, const struct location *end ) { - where->input_name = input_name ? input_name : "stdin"; - where->near_text = parser_text; - where->first_line = line_number; - where->last_line = line_number; + if (!begin) begin = &previous_location; + *where = *begin; + + if (end) + { + where->last_line = end->last_line; + where->last_column = end->last_column; + } + else + { + where->first_line = begin->last_line; + where->first_column = begin->last_column; + } }
void generic_msg( const struct location *where, const char *s, const char *t, va_list ap ) { - struct location cur_loc = CURRENT_LOCATION; - - if (!where) where = &cur_loc; + if (!where) where = &previous_location;
fprintf( stderr, "%s:%d: %s: ", where->input_name, where->first_line, t ); vfprintf( stderr, s, ap ); diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 35a392601e4..e92bd277771 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -125,8 +125,12 @@ static typelib_t *current_typelib; {
int parser_lex( PARSER_STYPE *yylval, PARSER_LTYPE *yylloc ); -void push_import( char *input_name ); -void pop_import(void); +void push_import( const char *fname, PARSER_LTYPE *yylloc ); +void pop_import( PARSER_LTYPE *yylloc ); + +# define YYLLOC_DEFAULT( cur, rhs, n ) \ + do { if (n) init_location( &(cur), &YYRHSLOC( rhs, 1 ), &YYRHSLOC( rhs, n ) ); \ + else init_location( &(cur), &YYRHSLOC( rhs, 0 ), NULL ); } while(0)
}
@@ -511,9 +515,9 @@ typedecl: cppquote: tCPPQUOTE '(' aSTRING ')' { $$ = $3; } ;
-import_start: tIMPORT aSTRING ';' { $$ = $2; push_import($2); } +import_start: tIMPORT aSTRING ';' { $$ = $2; push_import( $2, &yylloc ); } ; -import: import_start imp_statements aEOF { pop_import(); } +import: import_start imp_statements aEOF { pop_import( &yylloc ); } ;
importlib: tIMPORTLIB '(' aSTRING ')' @@ -1974,7 +1978,7 @@ var_t *make_var(char *name) init_declspec(&v->declspec, NULL); v->attrs = NULL; v->eval = NULL; - init_location( &v->where ); + init_location( &v->where, NULL, NULL ); v->declonly = FALSE; return v; } diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 8d4837b7943..b9173a33019 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -65,7 +65,7 @@ type_t *make_type(enum type_type type) t->tfswrite = FALSE; t->checked = FALSE; t->typelib_idx = -1; - init_location( &t->where ); + init_location( &t->where, NULL, NULL ); return t; }
@@ -478,7 +478,7 @@ type_t *type_new_alias(const decl_spec_t *t, const char *name) a->name = xstrdup(name); a->attrs = NULL; a->details.alias.aliasee = *t; - init_location( &a->where ); + init_location( &a->where, NULL, NULL );
return a; }