fix error output for unknown non-ascii characters
authorMatthias Braun <matthias.braun@kit.edu>
Fri, 25 May 2012 17:45:46 +0000 (19:45 +0200)
committerChristoph Mallon <christoph.mallon@gmx.de>
Sun, 17 Jun 2012 15:05:48 +0000 (17:05 +0200)
diagnostic.c
lexer.c
preprocessor.c

index c603f46..33bf313 100644 (file)
@@ -50,6 +50,25 @@ static void print_source_position(FILE *out, const source_position_t *pos)
                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.
  */
@@ -61,10 +80,12 @@ static void diagnosticvf(char const *fmt, va_list ap)
 
                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;
                        }
                }
@@ -82,8 +103,13 @@ 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;
                }
 
diff --git a/lexer.c b/lexer.c
index 4e36c3a..0212cfc 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -1110,7 +1110,7 @@ void lexer_next_preprocessing_token(void)
 
                default:
 dollar_sign:
-                       errorf(&lexer_pos, "unknown character '%c' found", c);
+                       errorf(&lexer_pos, "unknown character '%lc' found", c);
                        next_char();
                        break;
                }
index af95d90..e49390a 100644 (file)
@@ -1048,7 +1048,7 @@ restart:
                next_char();
                if (!ignore_unknown_chars) {
                        errorf(&pp_token.base.source_position,
-                              "unknown character '%c' found\n", input.c);
+                              "unknown character '%lc' found\n", input.c);
                        goto restart;
                } else {
                        pp_token.kind = input.c;