From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/parser.h | 2 +- tools/widl/parser.l | 69 +++++++++++++++++++++++++----------------- tools/widl/utils.c | 12 ++++++-- tools/widl/widltypes.h | 1 - 4 files changed, 52 insertions(+), 32 deletions(-)
diff --git a/tools/widl/parser.h b/tools/widl/parser.h index 8dfde433334..7fef1e755bd 100644 --- a/tools/widl/parser.h +++ b/tools/widl/parser.h @@ -25,7 +25,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_warning( const struct location *where, const char *message ); extern void parser_error( const struct location *where, const char *message ); extern void init_location( struct location *copy, const struct location *begin, const struct location *end );
diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 96772cd032f..9ed7adf97c4 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -461,6 +461,22 @@ SAFEARRAY{ws}*/( return tSAFEARRAY; } %%
+static void print_imports(void) +{ + struct import_state *state, *next; + + if (list_empty( &import_stack )) return; + + fprintf( stderr, "In file included from " ); + LIST_FOR_EACH_ENTRY_SAFE_REV( state, next, &import_stack, struct import_state, entry ) + { + if (&next->entry == &import_stack) break; + fprintf( stderr, "%s:%d,\n", state->input_name, state->where.first_line ); + fprintf( stderr, " from "); + } + fprintf( stderr, "%s:%d:\n", state->input_name, state->where.first_line ); +} + void pop_import( struct location *where ) { struct list *entry = list_head( &import_stack ); @@ -551,18 +567,6 @@ static void end_of_line( struct location *where ) where->last_column = 1; }
-static const int want_near_indication = 0; - -static void make_print(char *str) -{ - while(*str) - { - if(!isprint(*str)) - *str = ' '; - str++; - } -} - void init_location( struct location *where, const struct location *begin, const struct location *end ) { if (!begin) begin = &previous_location; @@ -580,30 +584,39 @@ void init_location( struct location *where, const struct location *begin, const } }
-void generic_msg( const struct location *where, const char *s, const char *t, va_list ap ) +static void diagnostic( const struct location *where, const char *type, const char *message ) { + char buffer[1024], *line = NULL; + FILE *file; + int i; + if (!where) where = &previous_location;
- fprintf( stderr, "%s:%d: %s: ", where->input_name, where->first_line, t ); - vfprintf( stderr, s, ap ); + print_imports();
- if (want_near_indication) - { - char *cpy; - if (where->near_text) - { - cpy = xstrdup( where->near_text ); - make_print( cpy ); - fprintf( stderr, " near '%s'", cpy ); - free( cpy ); - } - } + fprintf( stderr, "%s:%d:%d: %s: %s\n", where->input_name, where->first_line, where->first_column, type, message ); + + if (!where->input_name || !(file = fopen( where->input_name, "r" ))) return; + for (i = 0; i < where->first_line; i++) if (!(line = fgets( buffer, sizeof(buffer), file ))) break; + fclose( file ); + if (!line) return; + fprintf( stderr, "%s", line ); + + line = buffer; + for (i = 0; i < where->first_column - 1; i++) line += sprintf( line, " " ); + line += sprintf( line, "^" ); + for (i = where->first_column + 1; i < where->last_column; i++) line += sprintf( line, "~" ); + fprintf( stderr, "%s\n", buffer ); }
-/* yyerror: yacc assumes this is not newline terminated. */ void parser_error( const struct location *where, const char *message ) { - error_at( where, "%s\n", message ); + diagnostic( where, "error", message ); +} + +void parser_warning( const struct location *where, const char *message ) +{ + diagnostic( where, "warning", message ); }
static void warning_disable(int warning) diff --git a/tools/widl/utils.c b/tools/widl/utils.c index 987301d1585..4f2e9d3d602 100644 --- a/tools/widl/utils.c +++ b/tools/widl/utils.c @@ -34,10 +34,14 @@
void error_at( const struct location *where, const char *s, ... ) { + char buffer[1024]; + va_list ap; va_start( ap, s ); - generic_msg( where, s, "error", ap ); + vsnprintf( buffer, sizeof(buffer), s, ap ); va_end( ap ); + + parser_error( where, buffer ); exit( 1 ); }
@@ -62,10 +66,14 @@ void warning(const char *s, ...)
void warning_at( const struct location *where, const char *s, ... ) { + char buffer[1024]; + va_list ap; va_start( ap, s ); - generic_msg( where, s, "warning", ap ); + vsnprintf( buffer, sizeof(buffer), s, ap ); va_end( ap ); + + parser_warning( where, buffer ); }
void chat(const char *s, ...) diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index c3371e66871..fd108ecc473 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -313,7 +313,6 @@ enum type_basic_type struct location { const char *input_name; - const char *near_text; int first_line; int last_line; int first_column;