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(
678678 const kind = ZigClangStringLiteral_getKind(stmt);
679679 switch (kind) {
680680 .Ascii, .UTF8 => {
681 var len: usize = undefined;
682 const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &len);
681 var clen: usize = undefined;
682 const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &clen);
683683 const zstr = try rp.c.str(cstr);
684 const token = try appendTokenFmt(rp.c, .StringLiteral, "c\"{}\"", zstr); // TODO: escape string
684
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);
685695 const node = try rp.c.a().create(ast.Node.StringLiteral);
686696 node.* = ast.Node.StringLiteral{
687697 .base = ast.Node{ .id = .StringLiteral },
......@@ -704,6 +714,37 @@ fn transStringLiteral(
704714 }
705715}
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
707748fn transCCast(
708749 rp: RestorePoint,
709750 scope: *Scope,