X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=diagnostic.c;h=3e83b0b96df350f66260334f3a1cc8d461580bd8;hb=0d918ca248f8137f8d66ee7d1442c5b128ac0e4b;hp=9af64913b3edb9c1775e04aee6b0a75dc232d3a7;hpb=e344e920c9e6eac5f91e9e72ef44b2597e0114ab;p=cparser diff --git a/diagnostic.c b/diagnostic.c index 9af6491..3e83b0b 100644 --- a/diagnostic.c +++ b/diagnostic.c @@ -1,13 +1,32 @@ +/* + * This file is part of cparser. + * Copyright (C) 2007-2008 Matthias Braun + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ #include #include -#include "adt/error.h" -#include "ast.h" #include "diagnostic.h" +#include "adt/error.h" +#include "symbol_t.h" #include "token_t.h" +#include "ast.h" #include "type.h" - -//#define ABORT_ON_ERROR +#include "warning.h" /** Number of occurred diagnostics. */ unsigned diagnostic_count = 0; @@ -15,8 +34,19 @@ unsigned diagnostic_count = 0; unsigned error_count = 0; /** Number of occurred warnings. */ unsigned warning_count = 0; -/* true if warnings should be treated as errors */ -bool warnings_are_errors = false; +/** 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. @@ -98,7 +128,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 (;;) { @@ -119,6 +149,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"); } @@ -133,37 +169,74 @@ void diagnosticf(const char *const fmt, ...) va_list ap; va_start(ap, fmt); ++diagnostic_count; + curr_pos = NULL; diagnosticvf(fmt, ap); va_end(ap); } -void errorf(const source_position_t pos, const char *const fmt, ...) +static void errorvf(const source_position_t *pos, + const char *const fmt, va_list ap) { - va_list ap; - va_start(ap, fmt); - 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); - va_end(ap); fputc('\n', stderr); -#ifdef ABORT_ON_ERROR - abort(); -#endif + if (warning.fatal_errors) + exit(EXIT_FAILURE); +} + +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); } -void warningf(const source_position_t pos, const char *const fmt, ...) +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); + ++warning_count; + curr_pos = pos; + diagnosticvf(fmt, ap); + fputc('\n', stderr); +} + +void warningf(const source_position_t *pos, const char *const fmt, ...) +{ + if (inhibit_all_warnings) + return; + va_list ap; va_start(ap, fmt); - if (warnings_are_errors) { - fprintf(stderr, "%s:%u: error: ", pos.input_name, pos.linenr); - ++error_count; + curr_pos = pos; + if (warning.s_are_errors) { + errorvf(pos, fmt, ap); } else { - fprintf(stderr, "%s:%u: warning: ", pos.input_name, pos.linenr); - ++warning_count; + warningvf(pos, fmt, ap); } - diagnosticvf(fmt, ap); 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(); +}