Commit 57aa8997bd

Vexu <15308111+Vexu@users.noreply.github.com>
2019-07-21 13:35:45
fix escape sequence rendering
1 parent 16be70c
Changed files (2)
src/ast_render.cpp
@@ -319,6 +319,9 @@ static bool is_digit(uint8_t c) {
 }
 
 static bool is_printable(uint8_t c) {
+    if (c == 0) {
+        return false;
+    }
     static const uint8_t printables[] =
         " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.~`!@#$%^&*()_-+=\\{}[];'\"?/<>,:";
     for (size_t i = 0; i < array_length(printables); i += 1) {
@@ -337,20 +340,12 @@ static void string_literal_escape(Buf *source, Buf *dest) {
             buf_append_str(dest, "\\\"");
         } else if (c == '\\') {
             buf_append_str(dest, "\\\\");
-        } else if (c == '\a') {
-            buf_append_str(dest, "\\a");
-        } else if (c == '\b') {
-            buf_append_str(dest, "\\b");
-        } else if (c == '\f') {
-            buf_append_str(dest, "\\f");
         } else if (c == '\n') {
             buf_append_str(dest, "\\n");
         } else if (c == '\r') {
             buf_append_str(dest, "\\r");
         } else if (c == '\t') {
             buf_append_str(dest, "\\t");
-        } else if (c == '\v') {
-            buf_append_str(dest, "\\v");
         } else if (is_printable(c)) {
             buf_append_char(dest, c);
         } else {
@@ -630,7 +625,19 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
         case NodeTypeCharLiteral:
             {
                 uint8_t c = node->data.char_literal.value;
-                if (is_printable(c)) {
+                if (c == '\'') {
+                    fprintf(ar->f, "'\\''");
+                } else if (c == '\"') {
+                    fprintf(ar->f, "'\\\"'");
+                } else if (c == '\\') {
+                    fprintf(ar->f, "'\\\\'");
+                } else if (c == '\n') {
+                    fprintf(ar->f, "'\\n'");
+                } else if (c == '\r') {
+                    fprintf(ar->f, "'\\r'");
+                } else if (c == '\t') {
+                    fprintf(ar->f, "'\\t'");
+                } else if (is_printable(c)) {
                     fprintf(ar->f, "'%c'", c);
                 } else {
                     fprintf(ar->f, "'\\x%02x'", (int)c);
test/translate_c.zig
@@ -1780,6 +1780,40 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     );
 
+    cases.addC("escape sequences",
+        \\const char *escapes() {
+        \\char a = '\'',
+        \\    b = '\\',
+        \\    c = '\a',
+        \\    d = '\b',
+        \\    e = '\f',
+        \\    f = '\n',
+        \\    g = '\r',
+        \\    h = '\t',
+        \\    i = '\v',
+        \\    j = '\0',
+        \\    k = '\"';
+        \\    return "\'\\\a\b\f\n\r\t\v\0\"";
+        \\}
+        \\
+    ,
+        \\pub export fn escapes() [*c]const u8 {
+        \\    var a: u8 = u8('\'');
+        \\    var b: u8 = u8('\\');
+        \\    var c: u8 = u8('\x07');
+        \\    var d: u8 = u8('\x08');
+        \\    var e: u8 = u8('\x0c');
+        \\    var f: u8 = u8('\n');
+        \\    var g: u8 = u8('\r');
+        \\    var h: u8 = u8('\t');
+        \\    var i: u8 = u8('\x0b');
+        \\    var j: u8 = u8('\x00');
+        \\    var k: u8 = u8('\"');
+        \\    return c"\'\\\x07\x08\x0c\n\r\t\x0b\x00\"";
+        \\}
+        \\
+    );
+
     /////////////// Cases for only stage1 because stage2 behavior is better ////////////////
     cases.addC("Parameterless function prototypes",
         \\void foo() {}