/*
* This file is part of cparser.
- * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
- *
- * 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.
+ * Copyright (C) 2012 Matthias Braun <matze@braunis.de>
*/
#include <stdarg.h>
#include <stdio.h>
#include "diagnostic.h"
#include "adt/error.h"
#include "entity_t.h"
+#include "separator_t.h"
#include "symbol_t.h"
#include "token_t.h"
#include "ast.h"
bool show_column = true;
bool diagnostics_show_option = true;
-static const source_position_t *curr_pos = NULL;
+static const position_t *curr_pos = NULL;
/**
* prints an additional source position
*/
-static void print_source_position(FILE *out, const source_position_t *pos)
+static void print_position(FILE *out, const position_t *pos)
{
fprintf(out, "at line %u", pos->lineno);
if (show_column)
fprintf(out, " of \"%s\"", pos->input_name);
}
+static void fpututf32(utf32 const c, FILE *const out)
+{
+ if (c < 0x80U) {
+ fputc(c, out);
+ } else if (c < 0x800) {
+ fputc(0xC0 | (c >> 6), out);
+ fputc(0x80 | (c & 0x3F), out);
+ } else if (c < 0x10000) {
+ fputc(0xE0 | ( c >> 12), out);
+ fputc(0x80 | ((c >> 6) & 0x3F), out);
+ fputc(0x80 | ( c & 0x3F), out);
+ } else {
+ fputc(0xF0 | ( c >> 18), out);
+ fputc(0x80 | ((c >> 12) & 0x3F), out);
+ fputc(0x80 | ((c >> 6) & 0x3F), out);
+ fputc(0x80 | ( c & 0x3F), out);
+ }
+}
+
/**
* Issue a diagnostic message.
*/
bool extended = false;
bool flag_zero = false;
+ bool flag_long = false;
for (;; ++f) {
switch (*f) {
case '#': extended = true; break;
case '0': flag_zero = true; break;
+ case 'l': flag_long = true; break;
default: goto done_flags;
}
}
break;
case 'c': {
- const unsigned char val = (unsigned char) va_arg(ap, int);
- fputc(val, stderr);
+ if (flag_long) {
+ const utf32 val = va_arg(ap, utf32);
+ fpututf32(val, stderr);
+ } else {
+ const unsigned char val = (unsigned char) va_arg(ap, int);
+ fputc(val, stderr);
+ }
break;
}
}
case 'X': {
- unsigned int const val = va_arg(ap, unsigned int);
- char const *const fmt = flag_zero ? "%0*X" : "%*X";
- fprintf(stderr, fmt, field_width, val);
+ unsigned int const val = va_arg(ap, unsigned int);
+ char const *const xfmt = flag_zero ? "%0*X" : "%*X";
+ fprintf(stderr, xfmt, field_width, val);
break;
}
break;
}
- case 't': {
- const token_t *const token = va_arg(ap, const token_t*);
- print_pp_token(stderr, token);
- break;
- }
-
case 'K': {
const token_t* const token = va_arg(ap, const token_t*);
print_token(stderr, token);
case 'k': {
if (extended) {
- bool first = true;
- va_list* toks = va_arg(ap, va_list*);
- const char* const delimiter = va_arg(ap, const char*);
+ va_list* const toks = va_arg(ap, va_list*);
+ separator_t sep = { "", va_arg(ap, const char*) };
for (;;) {
const token_kind_t tok = (token_kind_t)va_arg(*toks, int);
if (tok == 0)
break;
- if (first) {
- first = false;
- } else {
- fputs(delimiter, stderr);
- }
+ fputs(sep_next(&sep), stderr);
print_token_kind(stderr, tok);
}
} else {
}
case 'P': {
- const source_position_t *pos = va_arg(ap, const source_position_t *);
- print_source_position(stderr, pos);
+ const position_t *pos = va_arg(ap, const position_t *);
+ print_position(stderr, pos);
break;
}
va_end(ap);
}
-static void diagnosticposvf(source_position_t const *const pos, char const *const kind, char const *const fmt, va_list ap)
+static void diagnosticposvf(position_t const *const pos, char const *const kind, char const *const fmt, va_list ap)
{
FILE *const out = stderr;
- fprintf(out, "%s:%u:", pos->input_name, pos->lineno);
- if (show_column)
- fprintf(out, "%u:", (unsigned)pos->colno);
- fprintf(out, " %s: ", kind);
+ if (pos) {
+ fprintf(out, "%s:", pos->input_name);
+ if (pos->lineno != 0) {
+ fprintf(out, "%u:", pos->lineno);
+ if (show_column)
+ fprintf(out, "%u:", (unsigned)pos->colno);
+ }
+ fputc(' ', out);
+ }
+ fprintf(out, "%s: ", kind);
curr_pos = pos;
diagnosticvf(fmt, ap);
}
-static void errorvf(const source_position_t *pos,
+static void errorvf(const position_t *pos,
const char *const fmt, va_list ap)
{
++error_count;
exit(EXIT_FAILURE);
}
-void errorf(const source_position_t *pos, const char *const fmt, ...)
+void errorf(const position_t *pos, const char *const fmt, ...)
{
va_list ap;
va_start(ap, fmt);
va_end(ap);
}
-void warningf(warning_t const warn, source_position_t const* pos, char const *const fmt, ...)
+void warningf(warning_t const warn, position_t const* pos, char const *const fmt, ...)
{
- va_list ap;
- va_start(ap, fmt);
+ if (pos->is_system_header && !is_warn_on(WARN_SYSTEM))
+ return;
+
warning_switch_t const *const s = get_warn_switch(warn);
switch ((unsigned) s->state) {
char const* kind;
++warning_count;
kind = "warning";
}
+ va_list ap;
+ va_start(ap, fmt);
diagnosticposvf(pos, kind, fmt, ap);
+ va_end(ap);
if (diagnostics_show_option)
fprintf(stderr, " [-W%s]\n", s->name);
+ else
+ fputc('\n', stderr);
break;
default:
break;
}
- va_end(ap);
}
-static void internal_errorvf(const source_position_t *pos,
+static void internal_errorvf(const position_t *pos,
const char *const fmt, va_list ap)
{
diagnosticposvf(pos, "internal error", fmt, ap);
fputc('\n', stderr);
}
-void internal_errorf(const source_position_t *pos, const char *const fmt, ...)
+void internal_errorf(const position_t *pos, const char *const fmt, ...)
{
va_list ap;
va_start(ap, fmt);