2 * This file is part of cparser.
3 * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 #include "diagnostic.h"
24 #include "adt/error.h"
32 /** Number of occurred diagnostics. */
33 unsigned diagnostic_count = 0;
34 /** Number of occurred errors. */
35 unsigned error_count = 0;
36 /** Number of occurred warnings. */
37 unsigned warning_count = 0;
38 bool show_column = true;
40 static const source_position_t *curr_pos = NULL;
43 * prints an additional source position
45 static void print_source_position(FILE *out, const source_position_t *pos)
47 fprintf(out, "at line %u", pos->lineno);
49 fprintf(out, ":%u", pos->colno);
50 if (curr_pos == NULL || curr_pos->input_name != pos->input_name)
51 fprintf(out, " of \"%s\"", pos->input_name);
55 * Issue a diagnostic message.
57 static void diagnosticvf(const char *const fmt, va_list ap)
59 for (const char* f = fmt; *f != '\0'; ++f) {
63 bool extended = false;
75 const unsigned char val = (unsigned char) va_arg(ap, int);
81 const int val = va_arg(ap, int);
82 fprintf(stderr, "%d", val);
87 const char* const str = va_arg(ap, const char*);
93 const string_t *str = va_arg(ap, const string_t*);
94 for (size_t i = 0; i < str->size; ++i) {
95 fputc(str->begin[i], stderr);
101 const unsigned int val = va_arg(ap, unsigned int);
102 fprintf(stderr, "%u", val);
107 const symbol_t *const symbol = va_arg(ap, const symbol_t*);
109 fputs("(null)", stderr);
111 fputs(symbol->string, stderr);
116 const expression_t* const expr = va_arg(ap, const expression_t*);
117 print_expression(expr);
122 const unsigned qualifiers = va_arg(ap, unsigned);
123 print_type_qualifiers(qualifiers, QUAL_SEP_NONE);
128 const type_t* const type = va_arg(ap, const type_t*);
129 const symbol_t* sym = NULL;
131 sym = va_arg(ap, const symbol_t*);
133 print_type_ext(type, sym, NULL);
138 const token_t *const token = va_arg(ap, const token_t*);
139 print_pp_token(stderr, token);
144 const token_t* const token = va_arg(ap, const token_t*);
145 print_token(stderr, token);
152 va_list* toks = va_arg(ap, va_list*);
153 const char* const delimiter = va_arg(ap, const char*);
155 const token_type_t tok = va_arg(*toks, token_type_t);
161 fputs(delimiter, stderr);
163 print_token_type(stderr, tok);
166 const token_type_t token = va_arg(ap, token_type_t);
167 print_token_type(stderr, token);
173 entity_t const *const ent = va_arg(ap, entity_t const*);
174 if (extended && is_declaration(ent)) {
175 print_type_ext(ent->declaration.type, ent->base.symbol, NULL);
177 char const *const kind = get_entity_kind_name(ent->kind);
178 symbol_t const *const sym = ent->base.symbol;
180 fprintf(stderr, "%s %s", kind, sym->string);
182 fprintf(stderr, "anonymous %s", kind);
189 const source_position_t *pos = va_arg(ap, const source_position_t *);
190 print_source_position(stderr, pos);
195 panic("unknown format specifier");
203 void diagnosticf(const char *const fmt, ...)
209 diagnosticvf(fmt, ap);
213 static void diagnosticposvf(source_position_t const *const pos, char const *const kind, char const *const fmt, va_list ap)
215 FILE *const out = stderr;
216 fprintf(out, "%s:%u:", pos->input_name, pos->lineno);
218 fprintf(out, "%u:", pos->colno);
219 fprintf(out, " %s: ", kind);
221 diagnosticvf(fmt, ap);
224 static void errorvf(const source_position_t *pos,
225 const char *const fmt, va_list ap)
229 diagnosticposvf(pos, "error", fmt, ap);
231 if (is_warn_on(WARN_FATAL_ERRORS))
235 void errorf(const source_position_t *pos, const char *const fmt, ...)
239 errorvf(pos, fmt, ap);
243 void warningf(warning_t const warn, source_position_t const* pos, char const *const fmt, ...)
247 warning_switch_t const *const s = get_warn_switch(warn);
254 if (is_warn_on(WARN_ERROR)) {
255 case WARN_LEVEL_ERROR:
262 diagnosticposvf(pos, kind, fmt, ap);
263 fprintf(stderr, " [-W%s]\n", s->name);
267 panic("invalid warning level");
272 static void internal_errorvf(const source_position_t *pos,
273 const char *const fmt, va_list ap)
275 diagnosticposvf(pos, "internal error", fmt, ap);
279 void internal_errorf(const source_position_t *pos, const char *const fmt, ...)
284 internal_errorvf(pos, fmt, ap);