From ab79e6bede3342cfb79485cac29eb7c5651997b4 Mon Sep 17 00:00:00 2001 From: Rangi Date: Fri, 9 Apr 2021 14:20:54 -0400 Subject: [PATCH] Change how `print(c)` formats reported characters Printable ASCII becomes single-quoted, using backslash escapes if necessary. Unprintable characters use 0xNN formatting, without quotes. --- src/asm/lexer.c | 10 +++++----- src/asm/util.c | 26 +++++++++++++++++--------- test/asm/garbage_char.err | 2 +- test/asm/invalid-utf-8.err | 4 ++-- test/asm/null-in-macro.err | 2 +- 5 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/asm/lexer.c b/src/asm/lexer.c index ca29fd5f..1d453b51 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -1172,7 +1172,7 @@ static void readLineContinuation(void) } else if (c == ';') { discardComment(); } else { - error("Begun line continuation, but encountered character '%s'\n", + error("Begun line continuation, but encountered character %s\n", print(c)); return; } @@ -1631,7 +1631,7 @@ static void readString(void) break; default: - error("Illegal character escape '%s'\n", print(c)); + error("Illegal character escape %s\n", print(c)); shiftChars(1); break; } @@ -1781,7 +1781,7 @@ static size_t appendStringLiteral(size_t i) break; default: - error("Illegal character escape '%s'\n", print(c)); + error("Illegal character escape %s\n", print(c)); shiftChars(1); break; } @@ -2069,7 +2069,7 @@ static int yylex_NORMAL(void) /* Do not report weird characters when capturing, it'll be done later */ if (!lexerState->capturing) { /* TODO: try to group reportings */ - error("Unknown character '%s'\n", print(c)); + error("Unknown character %s\n", print(c)); } } lexerState->atLineStart = false; @@ -2157,7 +2157,7 @@ static int yylex_RAW(void) */ default: - error("Illegal character escape '%s'\n", print(c)); + error("Illegal character escape %s\n", print(c)); break; } /* fallthrough */ diff --git a/src/asm/util.c b/src/asm/util.c index ff55a161..6f3b4658 100644 --- a/src/asm/util.c +++ b/src/asm/util.c @@ -32,35 +32,43 @@ uint32_t calchash(const char *s) char const *print(int c) { - static char buf[5]; /* '\xNN' + '\0' */ + // "'A'" + '\0': 4 bytes + // "'\\n'" + '\0': 5 bytes + // "0xFF" + '\0': 5 bytes + static char buf[5]; if (c == EOF) return "EOF"; if (isprint(c)) { - buf[0] = c; - buf[1] = '\0'; + buf[0] = '\''; + buf[1] = c; + buf[2] = '\''; + buf[3] = '\0'; return buf; } - buf[0] = '\\'; switch (c) { case '\n': - buf[1] = 'n'; + buf[2] = 'n'; break; case '\r': - buf[1] = 'r'; + buf[2] = 'r'; break; case '\t': - buf[1] = 't'; + buf[2] = 't'; break; default: /* Print as hex */ + buf[0] = '0'; buf[1] = 'x'; - sprintf(&buf[2], "%02hhx", (uint8_t)c); + snprintf(&buf[2], 3, "%02hhX", (uint8_t)c); // includes the '\0' return buf; } - buf[2] = '\0'; + buf[0] = '\''; + buf[1] = '\\'; + buf[3] = '\''; + buf[4] = '\0'; return buf; } diff --git a/test/asm/garbage_char.err b/test/asm/garbage_char.err index f75a19fa..d7bb40f3 100644 --- a/test/asm/garbage_char.err +++ b/test/asm/garbage_char.err @@ -1,3 +1,3 @@ ERROR: garbage_char.asm(1): - Unknown character '\xff' + Unknown character 0xFF error: Assembly aborted (1 error)! diff --git a/test/asm/invalid-utf-8.err b/test/asm/invalid-utf-8.err index 9698cd80..25352e6e 100644 --- a/test/asm/invalid-utf-8.err +++ b/test/asm/invalid-utf-8.err @@ -1,5 +1,5 @@ ERROR: invalid-utf-8.asm(6) -> invalid-utf-8.asm::m(4): - Unknown character '\xcf' + Unknown character 0xCF ERROR: invalid-utf-8.asm(6) -> invalid-utf-8.asm::m(4): - Unknown character '\xd3' + Unknown character 0xD3 error: Assembly aborted (2 errors)! diff --git a/test/asm/null-in-macro.err b/test/asm/null-in-macro.err index b90a7ac1..c9148b8a 100644 --- a/test/asm/null-in-macro.err +++ b/test/asm/null-in-macro.err @@ -1,3 +1,3 @@ ERROR: null-in-macro.asm(4) -> null-in-macro.asm::foo(2): - Unknown character '\x00' + Unknown character 0x00 error: Assembly aborted (1 error)!