authorgravatar for codroid@gmail.comhryx <codroid@gmail.com> 2019-06-24 22:37:19-07:00
committergravatar for codroid@gmail.comhryx <codroid@gmail.com> 2019-06-24 22:37:19-07:00
log84353515817929d694efd22e528e00e8de3d41a1
treeeba2c69f2021ff4eba733003981a63ad2d9174c4
parentf845994839697315aba7c4d4ce80d04d0d7b8ab0
signaturelock-open Commit is signed but in an unrecognized format.

Escape C string literals


1 files changed, 44 insertions(+), 3 deletions(-)

src-self-hosted/translate_c.zig+44-3
...@@ -678,10 +678,20 @@ fn transStringLiteral(...@@ -678,10 +678,20 @@ fn transStringLiteral(
678 const kind = ZigClangStringLiteral_getKind(stmt);678 const kind = ZigClangStringLiteral_getKind(stmt);
679 switch (kind) {679 switch (kind) {
680 .Ascii, .UTF8 => {680 .Ascii, .UTF8 => {
681 var len: usize = undefined;681 var clen: usize = undefined;
682 const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &len);682 const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &clen);
683 const zstr = try rp.c.str(cstr);683 const zstr = try rp.c.str(cstr);
684 const token = try appendTokenFmt(rp.c, .StringLiteral, "c\"{}\"", zstr); // TODO: escape string684
685 var len: usize = 0;
686 for (zstr) |c| len += escapeChar(c).len;
687
688 const buf = try rp.c.a().alloc(u8, len + "c\"\"".len);
689 buf[0] = 'c';
690 buf[1] = '"';
691 writeEscapedString(buf[2..], zstr);
692 buf[buf.len - 1] = '"';
693
694 const token = try appendToken(rp.c, .StringLiteral, buf);
685 const node = try rp.c.a().create(ast.Node.StringLiteral);695 const node = try rp.c.a().create(ast.Node.StringLiteral);
686 node.* = ast.Node.StringLiteral{696 node.* = ast.Node.StringLiteral{
687 .base = ast.Node{ .id = .StringLiteral },697 .base = ast.Node{ .id = .StringLiteral },
...@@ -704,6 +714,37 @@ fn transStringLiteral(...@@ -704,6 +714,37 @@ fn transStringLiteral(
704 }714 }
705}715}
706716
717fn escapedStringLen(s: []const u8) usize {
718 var len: usize = 0;
719 for (s) |c| len += escapeChar(c).len;
720 return len;
721}
722
723fn writeEscapedString(buf: []u8, s: []const u8) void {
724 var i: usize = 0;
725 for (s) |c| {
726 const escaped = escapeChar(c);
727 std.mem.copy(u8, buf[i..], escaped);
728 i += escaped.len;
729 }
730}
731
732fn escapeChar(c: u8) []const u8 {
733 // TODO: https://github.com/ziglang/zig/issues/2749
734 switch (c) {
735 // Printable ASCII except for ' " \
736 ' ', '!', '#'...'&', '('...'[', ']'...'~' => return ([_]u8{c})[0..],
737 '\'', '\"', '\\' => return ([_]u8{ '\\', c })[0..],
738 '\n' => return "\\n"[0..],
739 '\r' => return "\\r"[0..],
740 '\t' => return "\\t"[0..],
741 else => {
742 var buf: [4]u8 = undefined;
743 return std.fmt.bufPrint(buf[0..], "\\x{x2}", c) catch unreachable;
744 },
745 }
746}
747
707fn transCCast(748fn transCCast(
708 rp: RestorePoint,749 rp: RestorePoint,
709 scope: *Scope,750 scope: *Scope,