From 85c5f17dcd09540e31dc879166502984e483609d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sun, 18 Apr 2010 21:43:24 -0400 Subject: Have dmnsn_diagnostic() take a dmnsn_parse_location. --- dimension/common.prologue | 11 ++---- dimension/common.rules | 12 ++----- dimension/directives.prologue | 3 +- dimension/directives.rules | 20 ++++------- dimension/grammar.prologue | 3 +- dimension/lexer.l | 23 +++++++----- dimension/parse.c | 83 +++++++++++++++---------------------------- dimension/parse.h | 22 ++++++------ dimension/realize.c | 8 ++--- dimension/tokenize.c | 44 ++++++----------------- dimension/utility.c | 18 +++++++--- dimension/utility.h | 12 +++++-- 12 files changed, 103 insertions(+), 156 deletions(-) diff --git a/dimension/common.prologue b/dimension/common.prologue index 06ccdb3..d82b110 100644 --- a/dimension/common.prologue +++ b/dimension/common.prologue @@ -38,12 +38,7 @@ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ } else { \ - (Current).first_filename = (Current).last_filename = \ - YYRHSLOC(Rhs, 0).last_filename; \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC(Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC(Rhs, 0).last_column; \ + (Current) = YYRHSLOC(Rhs, 0); \ } \ } while (0) @@ -58,9 +53,7 @@ dmnsn_new_astnode(dmnsn_astnode_type type, YYLTYPE lloc) .ptr = NULL, .free_fn = NULL, .refcount = dmnsn_malloc(sizeof(unsigned int)), - .filename = lloc.first_filename, - .line = lloc.first_line, - .col = lloc.first_column + .location = lloc }; *astnode.refcount = 1; diff --git a/dimension/common.rules b/dimension/common.rules index cba3669..ff208f2 100644 --- a/dimension/common.rules +++ b/dimension/common.rules @@ -121,10 +121,7 @@ OBJECT: FINITE_SOLID_OBJECT { dmnsn_astnode *object = dmnsn_find_symbol(symtable, $3.ptr); if (!object) { - dmnsn_diagnostic(@3.first_filename, @3.first_line, - @3.first_column, - "unbound identifier '%s'", - (const char *)$3.ptr); + dmnsn_diagnostic(@3, "unbound identifier '%s'", (const char *)$3.ptr); dmnsn_delete_astnode($3); YYERROR; } else { @@ -165,8 +162,7 @@ OBJECT: FINITE_SOLID_OBJECT } default: - dmnsn_diagnostic(@3.first_filename, @3.first_line, - @3.first_column, + dmnsn_diagnostic(@3, "identifier '%s' is a %s; expected an object type", (const char *)$3.ptr, dmnsn_astnode_string(object->type)); @@ -844,9 +840,7 @@ COLOR_KEYWORD_GROUP_INIT: /* empty */ { COLOR_KEYWORD_ITEM: IDENTIFIER { dmnsn_astnode *symbol = dmnsn_find_symbol(symtable, $1.ptr); if (!symbol) { - dmnsn_diagnostic(@1.first_filename, @1.first_line, - @1.first_column, - "unbound identifier '%s'", + dmnsn_diagnostic(@1, "unbound identifier '%s'", (const char *)$1.ptr); dmnsn_delete_astnode($1); YYERROR; diff --git a/dimension/directives.prologue b/dimension/directives.prologue index 3649bed..0bb7cad 100644 --- a/dimension/directives.prologue +++ b/dimension/directives.prologue @@ -23,8 +23,7 @@ void yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, dmnsn_symbol_table *symtable, const char *str) { - dmnsn_diagnostic(locp->first_filename, locp->first_line, locp->first_column, - "%s", str); + dmnsn_diagnostic(*locp, "%s", str); } static int diff --git a/dimension/directives.rules b/dimension/directives.rules index 82bdd8f..e199fe3 100644 --- a/dimension/directives.rules +++ b/dimension/directives.rules @@ -47,10 +47,8 @@ LANGUAGE_DIRECTIVE: "#include" STRING { dmnsn_delete_astnode($3); } | "#version" FLOAT ";" { - dmnsn_diagnostic(@$.first_filename, @$.first_line, - @$.first_column, - "WARNING: POV-Ray #version" - " backwards-compatibility not supported"); + dmnsn_diagnostic(@$, "WARNING: POV-Ray #version backwards-" + "compatibility not supported"); dmnsn_delete_astnode($2); } | "#debug" STRING { @@ -58,15 +56,11 @@ LANGUAGE_DIRECTIVE: "#include" STRING { dmnsn_delete_astnode($2); } | "#warning" STRING { - dmnsn_diagnostic(@$.first_filename, @$.first_line, - @$.first_column, - "WARNING: %s", (const char *)$2.ptr); + dmnsn_diagnostic(@$, "WARNING: %s", (const char *)$2.ptr); dmnsn_delete_astnode($2); } | "#error" STRING { - dmnsn_diagnostic(@$.first_filename, @$.first_line, - @$.first_column, - "%s", (const char *)$2.ptr); + dmnsn_diagnostic(@$, "%s", (const char *)$2.ptr); dmnsn_delete_astnode($2); YYERROR; } @@ -87,10 +81,8 @@ LANGUAGE_DIRECTIVE: "#include" STRING { unsigned int nparams_given = dmnsn_array_size($3.children); if (nparams_given != nparams) { - dmnsn_diagnostic(@$.first_filename, @$.first_line, - @$.first_column, - "wrong number of macro arguments" - " (%u; should be %u)", + dmnsn_diagnostic(@$, "wrong number of macro arguments" + " (%u; should be %u)", nparams_given, nparams); dmnsn_delete_astnode($3); YYERROR; diff --git a/dimension/grammar.prologue b/dimension/grammar.prologue index 6f8e312..9a00b89 100644 --- a/dimension/grammar.prologue +++ b/dimension/grammar.prologue @@ -23,6 +23,5 @@ void yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, dmnsn_astree *astree, dmnsn_symbol_table *symtable, const char *str) { - dmnsn_diagnostic(locp->first_filename, locp->first_line, locp->first_column, - "%s", str); + dmnsn_diagnostic(*locp, "%s", str); } diff --git a/dimension/lexer.l b/dimension/lexer.l index 2684868..f4685b8 100644 --- a/dimension/lexer.l +++ b/dimension/lexer.l @@ -54,7 +54,8 @@ lvalp->value = NULL; \ llocp->first_filename = llocp->last_filename = filename; \ llocp->first_line = llocp->last_line = yylineno; \ - llocp->first_column = llocp->last_column = yycolumn; \ + llocp->first_column = yycolumn; \ + llocp->last_column = yycolumn + yyleng; \ } while (0) #define CALCULATE_COLUMN() do { yycolumn += yyleng; } while (0) @@ -296,9 +297,9 @@ unsigned long wchar; #[\b\r\t\v ]*while RETURN_TOKEN(DMNSN_T_WHILE); #[\b\r\t\v ]*write RETURN_TOKEN(DMNSN_T_WRITE); #[\b\r\t\v ]*[[:alnum:]_]* { - dmnsn_diagnostic(filename, yylineno, yycolumn, - "unrecognized language directive '%s'", yytext); - RETURN_TOKEN(DMNSN_T_LEX_ERROR); + NEW_TOKEN(DMNSN_T_LEX_ERROR); + dmnsn_diagnostic(*llocp, "unrecognized language directive '%s'", yytext); + RETURN(); } (?# Identifiers) @@ -334,8 +335,12 @@ unsigned long wchar; yy_pop_state(yyscanner); } . { - dmnsn_diagnostic(filename, yylineno, yycolumn, - "WARNING: unrecognised escape sequence '\\%c'", + dmnsn_parse_location location; + location.first_filename = location.last_filename = filename; + location.first_line = location.last_line = yylineno; + location.first_column = yycolumn; + location.last_column = yycolumn + yyleng; + dmnsn_diagnostic(location, "WARNING: unrecognised escape sequence '\\%c'", (int)*yytext); STRCAT(yytext, yyleng); yy_pop_state(yyscanner); @@ -347,10 +352,10 @@ unsigned long wchar; (?# Fall-through) . { - dmnsn_diagnostic(filename, yylineno, yycolumn, - "unrecognized character '%c' (0x%X)", + NEW_TOKEN(DMNSN_T_LEX_ERROR); + dmnsn_diagnostic(*llocp, "unrecognized character '%c' (0x%X)", (int)*yytext, (unsigned int)(unsigned char)*yytext); - RETURN_TOKEN(DMNSN_T_LEX_ERROR); + RETURN(); } %% diff --git a/dimension/parse.c b/dimension/parse.c index 4d27be6..e4f3bf3 100644 --- a/dimension/parse.c +++ b/dimension/parse.c @@ -328,9 +328,7 @@ dmnsn_new_astnode(dmnsn_astnode_type type) .ptr = NULL, .free_fn = NULL, .refcount = dmnsn_malloc(sizeof(unsigned int)), - .filename = "", - .line = -1, - .col = -1, + .location = { "", "", -1, -1, -1, -1 } }; *astnode.refcount = 0; @@ -491,9 +489,7 @@ dmnsn_copy_astnode(dmnsn_astnode astnode) .children = dmnsn_new_array(sizeof(dmnsn_astnode)), .ptr = NULL, .refcount = dmnsn_malloc(sizeof(unsigned int)), - .filename = astnode.filename, - .line = astnode.line, - .col = astnode.col + .location = astnode.location }; *copy.refcount = 1; @@ -600,8 +596,7 @@ dmnsn_eval_zeroary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) break; default: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "invalid constant '%s'", + dmnsn_diagnostic(astnode.location, "invalid constant '%s'", dmnsn_astnode_string(astnode.type)); ret.type = DMNSN_AST_NONE; break; @@ -797,8 +792,7 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) } default: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "invalid unary operator '%s' on %s", + dmnsn_diagnostic(astnode.location, "invalid unary operator '%s' on %s", dmnsn_astnode_string(astnode.type), dmnsn_astnode_string(rhs.type)); ret.type = DMNSN_AST_NONE; @@ -902,8 +896,7 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) } default: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "invalid unary operator '%s' on %s", + dmnsn_diagnostic(astnode.location, "invalid unary operator '%s' on %s", dmnsn_astnode_string(astnode.type), dmnsn_astnode_string(rhs.type)); ret.type = DMNSN_AST_NONE; @@ -926,8 +919,7 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) if (*endptr != '\0' || endptr == rhs.ptr) { double d = strtod(rhs.ptr, &endptr); if (*endptr != '\0' || endptr == rhs.ptr) { - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "invalid numeric string '%s'", + dmnsn_diagnostic(astnode.location, "invalid numeric string '%s'", (const char *)rhs.ptr); ret.type = DMNSN_AST_NONE; } else { @@ -940,16 +932,14 @@ dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) } default: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "invalid unary operator '%s' on %s", + dmnsn_diagnostic(astnode.location, "invalid unary operator '%s' on %s", dmnsn_astnode_string(astnode.type), dmnsn_astnode_string(rhs.type)); ret.type = DMNSN_AST_NONE; break; } } else { - dmnsn_diagnostic(rhs.filename, rhs.line, rhs.col, - "expected %s or %s or %s; found %s", + dmnsn_diagnostic(rhs.location, "expected %s or %s or %s; found %s", dmnsn_astnode_string(DMNSN_AST_INTEGER), dmnsn_astnode_string(DMNSN_AST_FLOAT), dmnsn_astnode_string(DMNSN_AST_STRING), @@ -1134,7 +1124,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) case DMNSN_AST_LESS_EQUAL: case DMNSN_AST_GREATER: case DMNSN_AST_GREATER_EQUAL: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, + dmnsn_diagnostic(astnode.location, "invalid comparison operator '%s' between vectors", dmnsn_astnode_string(astnode.type)); ret = dmnsn_copy_astnode(astnode); @@ -1317,7 +1307,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) break; default: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, + dmnsn_diagnostic(astnode.location, "invalid binary operator '%s' on %s and %s", dmnsn_astnode_string(astnode.type), dmnsn_astnode_string(lhs.type), @@ -1344,8 +1334,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) break; case DMNSN_AST_DIV: if (r == 0) { - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "WARNING: division by zero"); + dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); dmnsn_make_ast_float(&ret, (double)l/0.0); } else if (l%r == 0) { dmnsn_make_ast_integer(&ret, l/r); @@ -1384,8 +1373,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) break; case DMNSN_AST_INT_DIV: if (r == 0) { - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "WARNING: division by zero"); + dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); dmnsn_make_ast_float(&ret, (double)l/0.0); } else { dmnsn_make_ast_integer(&ret, l/r); @@ -1399,8 +1387,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) break; case DMNSN_AST_MOD: if (r == 0) { - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "WARNING: division by zero"); + dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); dmnsn_make_ast_float(&ret, fmod(l, 0.0)); } else { dmnsn_make_ast_integer(&ret, l%r); @@ -1424,7 +1411,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) break; default: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, + dmnsn_diagnostic(astnode.location, "invalid binary operator '%s' on %s and %s", dmnsn_astnode_string(astnode.type), dmnsn_astnode_string(lhs.type), @@ -1442,8 +1429,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) } else if (lhs.type == DMNSN_AST_FLOAT) { l = *(double *)lhs.ptr; } else { - dmnsn_diagnostic(lhs.filename, lhs.line, lhs.col, - "expected %s or %s; found %s", + dmnsn_diagnostic(lhs.location, "expected %s or %s; found %s", dmnsn_astnode_string(DMNSN_AST_INTEGER), dmnsn_astnode_string(DMNSN_AST_FLOAT), dmnsn_astnode_string(lhs.type)); @@ -1458,8 +1444,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) } else if (rhs.type == DMNSN_AST_FLOAT) { r = *(double *)rhs.ptr; } else { - dmnsn_diagnostic(rhs.filename, rhs.line, rhs.col, - "expected %s or %s; found %s", + dmnsn_diagnostic(rhs.location, "expected %s or %s; found %s", dmnsn_astnode_string(DMNSN_AST_INTEGER), dmnsn_astnode_string(DMNSN_AST_FLOAT), dmnsn_astnode_string(rhs.type)); @@ -1480,10 +1465,8 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) dmnsn_make_ast_float(&ret, l*r); break; case DMNSN_AST_DIV: - if (r == 0.0) { - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "WARNING: division by zero"); - } + if (r == 0.0) + dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); dmnsn_make_ast_float(&ret, l/r); break; @@ -1518,10 +1501,8 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) dmnsn_make_ast_float(&ret, atan2(l, r)); break; case DMNSN_AST_INT_DIV: - if (r == 0.0) { - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "WARNING: division by zero"); - } + if (r == 0.0) + dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); dmnsn_make_ast_maybe_integer(&ret, trunc(l/r)); break; case DMNSN_AST_MAX: @@ -1555,10 +1536,8 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) } break; case DMNSN_AST_MOD: - if (r == 0.0) { - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "WARNING: division by zero"); - } + if (r == 0.0) + dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); dmnsn_make_ast_float(&ret, fmod(l, r)); break; case DMNSN_AST_POW: @@ -1579,7 +1558,7 @@ dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) break; default: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, + dmnsn_diagnostic(astnode.location, "invalid binary operator '%s' on %s and %s", dmnsn_astnode_string(astnode.type), dmnsn_astnode_string(lhs.type), @@ -1611,8 +1590,7 @@ dmnsn_eval_ternary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) break; default: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "invalid ternary operator '%s'", + dmnsn_diagnostic(astnode.location, "invalid ternary operator '%s'", dmnsn_astnode_string(astnode.type)); ret = dmnsn_copy_astnode(astnode); ret.type = DMNSN_AST_NONE; @@ -1644,13 +1622,11 @@ dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) dmnsn_astnode *symbol = dmnsn_find_symbol(symtable, astnode.ptr); if (symbol) { dmnsn_astnode id = *symbol; - id.filename = astnode.filename; - id.line = astnode.line; - id.col = astnode.col; + id.location = astnode.location; return dmnsn_eval(id, symtable); } else { - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "unbound identifier '%s'", (const char *)astnode.ptr); + dmnsn_diagnostic(astnode.location, "unbound identifier '%s'", + (const char *)astnode.ptr); dmnsn_astnode error = dmnsn_new_astnode(DMNSN_AST_NONE); ++*error.refcount; return error; @@ -1731,7 +1707,7 @@ dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) return dmnsn_eval_ternary(astnode, symtable); default: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, + dmnsn_diagnostic(astnode.location, "expected arithmetic expression; found %s", dmnsn_astnode_string(astnode.type)); dmnsn_astnode error = dmnsn_new_astnode(DMNSN_AST_NONE); @@ -1749,8 +1725,7 @@ dmnsn_eval_scalar(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) if (ret.type != DMNSN_AST_INTEGER && ret.type != DMNSN_AST_FLOAT && ret.type != DMNSN_AST_NONE) { - dmnsn_diagnostic(ret.filename, ret.line, ret.col, - "expected %s or %s; found %s", + dmnsn_diagnostic(ret.location, "expected %s or %s; found %s", dmnsn_astnode_string(DMNSN_AST_INTEGER), dmnsn_astnode_string(DMNSN_AST_FLOAT), dmnsn_astnode_string(ret.type)); diff --git a/dimension/parse.h b/dimension/parse.h index 6e5ef09..3a830b8 100644 --- a/dimension/parse.h +++ b/dimension/parse.h @@ -165,8 +165,16 @@ typedef enum { DMNSN_AST_MACRO } dmnsn_astnode_type; +typedef struct dmnsn_astnode dmnsn_astnode; + +typedef struct dmnsn_parse_location { + const char *first_filename, *last_filename; + int first_line, last_line; + int first_column, last_column; +} dmnsn_parse_location; + /* Abstract syntax tree node (a dmnsn_array* of these is an AST) */ -typedef struct dmnsn_astnode { +struct dmnsn_astnode { dmnsn_astnode_type type; /* Child nodes */ @@ -180,9 +188,8 @@ typedef struct dmnsn_astnode { unsigned int *refcount; /* File name, and line and column numbers from source code */ - const char *filename; - int line, col; -} dmnsn_astnode; + dmnsn_parse_location location; +}; typedef dmnsn_array dmnsn_astree; @@ -241,13 +248,6 @@ dmnsn_astree *dmnsn_parse_string(const char *str, dmnsn_symbol_table *symtable); /* * Parser internals */ - -typedef struct dmnsn_parse_location { - const char *first_filename, *last_filename; - int first_line, last_line; - int first_column, last_column; -} dmnsn_parse_location; - typedef union dmnsn_parse_item { char *value; dmnsn_astnode astnode; diff --git a/dimension/realize.c b/dimension/realize.c index d0b8fa2..b6c6a60 100644 --- a/dimension/realize.c +++ b/dimension/realize.c @@ -31,8 +31,7 @@ dmnsn_realize_integer(dmnsn_astnode astnode) case DMNSN_AST_INTEGER: return *(long *)astnode.ptr; case DMNSN_AST_FLOAT: - dmnsn_diagnostic(astnode.filename, astnode.line, astnode.col, - "WARNING: float rounded to integer"); + dmnsn_diagnostic(astnode.location, "WARNING: float rounded to integer"); return *(double *)astnode.ptr; default: @@ -192,8 +191,7 @@ dmnsn_realize_global_settings(dmnsn_astnode astnode, dmnsn_scene *scene) switch (item.type) { case DMNSN_AST_ASSUMED_GAMMA: - dmnsn_diagnostic(item.filename, item.line, item.col, - "WARNING: assumed_gamma not supported"); + dmnsn_diagnostic(item.location, "WARNING: assumed_gamma not supported"); break; case DMNSN_AST_MAX_TRACE_LEVEL: @@ -758,7 +756,7 @@ dmnsn_realize_light_source_modifiers(dmnsn_astnode astnode, dmnsn_light *light) case DMNSN_AST_PIGMENT: case DMNSN_AST_FINISH: case DMNSN_AST_INTERIOR: - dmnsn_diagnostic(modifier.filename, modifier.line, modifier.col, + dmnsn_diagnostic(modifier.location, "WARNING: ignoring %s applied to light source", dmnsn_astnode_string(modifier.type)); break; diff --git a/dimension/tokenize.c b/dimension/tokenize.c index 1fddea3..c821a3c 100644 --- a/dimension/tokenize.c +++ b/dimension/tokenize.c @@ -101,9 +101,7 @@ dmnsn_buffer_balanced(dmnsn_token_buffer *tbuffer, bool recursive, } if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(buffered.lloc.first_filename, buffered.lloc.first_line, - buffered.lloc.first_column, - "syntax error, unexpected end-of-file"); + dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); return 1; } else if (buffered.type == DMNSN_T_LEX_ERROR) { return 1; @@ -143,9 +141,7 @@ dmnsn_buffer_strexp(dmnsn_token_buffer *tbuffer, bool recursive, } if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(buffered.lloc.first_filename, buffered.lloc.first_line, - buffered.lloc.first_column, - "syntax error, unexpected end-of-file"); + dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); return 1; } else if (buffered.type == DMNSN_T_LEX_ERROR) { return 1; @@ -229,9 +225,7 @@ dmnsn_include_buffer(int token, dmnsn_token_buffer *prev, FILE *file = fopen(local_include, "r"); if (!file) { - dmnsn_diagnostic(llocp->first_filename, llocp->first_line, - llocp->first_column, - "Couldn't open include file '%s'", include); + dmnsn_diagnostic(*llocp, "Couldn't open include file '%s'", include); dmnsn_undef_symbol(symtable, "$include"); free(local_include); dmnsn_delete_token_buffer(tbuffer); @@ -241,9 +235,7 @@ dmnsn_include_buffer(int token, dmnsn_token_buffer *prev, void *buffer = dmnsn_yy_make_buffer(file, yyscanner); if (!buffer) { - dmnsn_diagnostic(llocp->first_filename, llocp->first_line, - llocp->first_column, - "Couldn't allocate buffer for include file '%s'", + dmnsn_diagnostic(*llocp, "Couldn't allocate buffer for include file '%s'", include); dmnsn_undef_symbol(symtable, "$include"); fclose(file); @@ -300,9 +292,7 @@ dmnsn_declaration_buffer(int token, dmnsn_token_buffer *prev, filename, symtable, yyscanner); if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(filename, buffered.lloc.first_line, - buffered.lloc.first_column, - "syntax error, unexpected end-of-file"); + dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); dmnsn_delete_token_buffer(tbuffer); return NULL; } else if (buffered.type == DMNSN_T_LEX_ERROR) { @@ -357,9 +347,7 @@ dmnsn_undef_buffer(int token, dmnsn_token_buffer *prev, filename, symtable, yyscanner); if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(filename, buffered.lloc.first_line, - buffered.lloc.first_column, - "syntax error, unexpected end-of-file"); + dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); dmnsn_delete_token_buffer(tbuffer); return NULL; } else if (buffered.type == DMNSN_T_LEX_ERROR) { @@ -441,9 +429,7 @@ dmnsn_if_buffer(int token, dmnsn_token_buffer *prev, filename, symtable, yyscanner); if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(filename, buffered.lloc.first_line, - buffered.lloc.first_column, - "syntax error, unexpected end-of-file"); + dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); dmnsn_delete_token_buffer(tbuffer); return NULL; } @@ -472,9 +458,7 @@ dmnsn_if_buffer(int token, dmnsn_token_buffer *prev, if (else_seen || (tbuffer->prev && tbuffer->prev->type == DMNSN_T_WHILE)) { - dmnsn_diagnostic(filename, buffered.lloc.first_line, - buffered.lloc.first_column, - "syntax error, unexpected #else"); + dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected #else"); dmnsn_delete_token_buffer(tbuffer); return NULL; } else { @@ -518,9 +502,7 @@ dmnsn_while_buffer(int token, dmnsn_token_buffer *prev, filename, symtable, yyscanner); if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(filename, buffered.lloc.first_line, - buffered.lloc.first_column, - "syntax error, unexpected end-of-file"); + dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); dmnsn_delete_token_buffer(tbuffer); return NULL; } @@ -576,9 +558,7 @@ dmnsn_version_buffer(int token, dmnsn_token_buffer *prev, filename, symtable, yyscanner); if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(filename, buffered.lloc.first_line, - buffered.lloc.first_column, - "syntax error, unexpected end-of-file"); + dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); dmnsn_delete_token_buffer(tbuffer); return NULL; } else if (buffered.type == DMNSN_T_LEX_ERROR) { @@ -688,9 +668,7 @@ dmnsn_declare_macro(int token, dmnsn_token_buffer *prev, filename, symtable, yyscanner); if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(filename, buffered.lloc.first_line, - buffered.lloc.first_column, - "syntax error, unexpected end-of-file"); + dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); dmnsn_delete_token_buffer(tbuffer); return false; } diff --git a/dimension/utility.c b/dimension/utility.c index 54dd78a..17a7bba 100644 --- a/dimension/utility.c +++ b/dimension/utility.c @@ -22,16 +22,24 @@ #include void -dmnsn_diagnostic(const char *filename, int line, int col, const char *format, - ...) +dmnsn_diagnostic(dmnsn_parse_location location, const char *format, ...) { va_list ap; va_start(ap, format); - if (line >= 0 && col >= 0) { - fprintf(stderr, "%s:%d:%d: ", filename, line, col); + if (location.first_line >= 0 && location.first_column >= 0) { + if (location.first_line != location.last_line) { + fprintf(stderr, "%s:%d-%d: ", location.first_filename, + location.first_line, location.last_line); + } else if (location.first_column != location.last_column - 1) { + fprintf(stderr, "%s:%d:%d-%d: ", location.first_filename, + location.first_line, location.first_column, location.last_column); + } else { + fprintf(stderr, "%s:%d:%d: ", location.first_filename, + location.first_line, location.first_column); + } } else { - fprintf(stderr, "%s: ", filename); + fprintf(stderr, "%s: ", location.first_filename); } vfprintf(stderr, format, ap); fprintf(stderr, "\n"); diff --git a/dimension/utility.h b/dimension/utility.h index beb818e..15ceadb 100644 --- a/dimension/utility.h +++ b/dimension/utility.h @@ -17,6 +17,11 @@ * along with this program. If not, see . * *************************************************************************/ +#ifndef UTILITY_H +#define UTILITY_H + +#include "parse.h" /* For dmnsn_parse_location */ + #if defined(__GNUC__) || defined(__attribute__) #define DMNSN_PRINTF_WARN(f, a) __attribute__((format (printf, f, a))) #else @@ -24,6 +29,7 @@ #endif /* Print a parsing diagnostic to stderr */ -void dmnsn_diagnostic(const char *filename, int line, int col, - const char *format, ...) - DMNSN_PRINTF_WARN(4, 5); +void dmnsn_diagnostic(dmnsn_parse_location location, const char *format, ...) + DMNSN_PRINTF_WARN(2, 3); + +#endif /* UTILITY_H */ -- cgit v1.2.3