X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=diagnostic.c;h=4a9122c8701978f9c53629f3742c801987760c6b;hb=1fed691f0daf9eb74d4726868048766323adfe67;hp=02008d9a4128680a61d492b8cc4d3a5e98380300;hpb=f3f57226195059ecb38d482c469a4c665fc9c2d1;p=cparser diff --git a/diagnostic.c b/diagnostic.c index 02008d9..4a9122c 100644 --- a/diagnostic.c +++ b/diagnostic.c @@ -37,6 +37,17 @@ unsigned warning_count = 0; /** true if warnings should be inhibited */ bool inhibit_all_warnings = false; +static const source_position_t *curr_pos = NULL; + +/** + * prints an additional source position + */ +static void print_source_position(FILE *out, const source_position_t *pos) { + fprintf(out, "at line %u", pos->linenr); + if (curr_pos == NULL || curr_pos->input_name != pos->input_name) + fprintf(out, " of \"%s\"", pos->input_name); +} + /** * Issue a diagnostic message. */ @@ -83,7 +94,10 @@ static void diagnosticvf(const char *const fmt, va_list ap) case 'Y': { const symbol_t *const symbol = va_arg(ap, const symbol_t*); - fputs(symbol->string, stderr); + if (symbol == NULL) + fputs("(null)", stderr); + else + fputs(symbol->string, stderr); break; } @@ -117,7 +131,7 @@ static void diagnosticvf(const char *const fmt, va_list ap) case 'k': { if (extended) { - bool first = false; + bool first = true; va_list* toks = va_arg(ap, va_list*); const char* const delimiter = va_arg(ap, const char*); for (;;) { @@ -138,6 +152,12 @@ static void diagnosticvf(const char *const fmt, va_list ap) break; } + case 'P': { + const source_position_t *pos = va_arg(ap, const source_position_t *); + print_source_position(stderr, pos); + break; + } + default: panic("unknown format specifier"); } @@ -152,15 +172,17 @@ void diagnosticf(const char *const fmt, ...) va_list ap; va_start(ap, fmt); ++diagnostic_count; + curr_pos = NULL; diagnosticvf(fmt, ap); va_end(ap); } -static void errorvf(const source_position_t pos, +static void errorvf(const source_position_t *pos, const char *const fmt, va_list ap) { - fprintf(stderr, "%s:%u: error: ", pos.input_name, pos.linenr); + fprintf(stderr, "%s:%u: error: ", pos->input_name, pos->linenr); ++error_count; + curr_pos = pos; diagnosticvf(fmt, ap); fputc('\n', stderr); @@ -168,30 +190,33 @@ static void errorvf(const source_position_t pos, exit(EXIT_FAILURE); } -void errorf(const source_position_t pos, const char *const fmt, ...) +void errorf(const source_position_t *pos, const char *const fmt, ...) { va_list ap; va_start(ap, fmt); + curr_pos = pos; errorvf(pos, fmt, ap); va_end(ap); } -static void warningvf(const source_position_t pos, +static void warningvf(const source_position_t *pos, const char *const fmt, va_list ap) { - fprintf(stderr, "%s:%u: warning: ", pos.input_name, pos.linenr); + fprintf(stderr, "%s:%u: warning: ", pos->input_name, pos->linenr); ++warning_count; + curr_pos = pos; diagnosticvf(fmt, ap); fputc('\n', stderr); } -void warningf(const source_position_t pos, const char *const fmt, ...) +void warningf(const source_position_t *pos, const char *const fmt, ...) { if (inhibit_all_warnings) return; va_list ap; va_start(ap, fmt); + curr_pos = pos; if (warning.s_are_errors) { errorvf(pos, fmt, ap); } else { @@ -199,3 +224,22 @@ void warningf(const source_position_t pos, const char *const fmt, ...) } va_end(ap); } + +static void internal_errorvf(const source_position_t *pos, + const char *const fmt, va_list ap) +{ + fprintf(stderr, "%s:%u: internal error: ", pos->input_name, pos->linenr); + curr_pos = pos; + diagnosticvf(fmt, ap); + fputc('\n', stderr); +} + +void internal_errorf(const source_position_t *pos, const char *const fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + curr_pos = pos; + internal_errorvf(pos, fmt, ap); + va_end(ap); + abort(); +}