Commit 8435351581
Changed files (1)
src-self-hosted
src-self-hosted/translate_c.zig
@@ -678,10 +678,20 @@ fn transStringLiteral(
const kind = ZigClangStringLiteral_getKind(stmt);
switch (kind) {
.Ascii, .UTF8 => {
- var len: usize = undefined;
- const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &len);
+ var clen: usize = undefined;
+ const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &clen);
const zstr = try rp.c.str(cstr);
- const token = try appendTokenFmt(rp.c, .StringLiteral, "c\"{}\"", zstr); // TODO: escape string
+
+ var len: usize = 0;
+ for (zstr) |c| len += escapeChar(c).len;
+
+ const buf = try rp.c.a().alloc(u8, len + "c\"\"".len);
+ buf[0] = 'c';
+ buf[1] = '"';
+ writeEscapedString(buf[2..], zstr);
+ buf[buf.len - 1] = '"';
+
+ const token = try appendToken(rp.c, .StringLiteral, buf);
const node = try rp.c.a().create(ast.Node.StringLiteral);
node.* = ast.Node.StringLiteral{
.base = ast.Node{ .id = .StringLiteral },
@@ -704,6 +714,37 @@ fn transStringLiteral(
}
}
+fn escapedStringLen(s: []const u8) usize {
+ var len: usize = 0;
+ for (s) |c| len += escapeChar(c).len;
+ return len;
+}
+
+fn writeEscapedString(buf: []u8, s: []const u8) void {
+ var i: usize = 0;
+ for (s) |c| {
+ const escaped = escapeChar(c);
+ std.mem.copy(u8, buf[i..], escaped);
+ i += escaped.len;
+ }
+}
+
+fn escapeChar(c: u8) []const u8 {
+ // TODO: https://github.com/ziglang/zig/issues/2749
+ switch (c) {
+ // Printable ASCII except for ' " \
+ ' ', '!', '#'...'&', '('...'[', ']'...'~' => return ([_]u8{c})[0..],
+ '\'', '\"', '\\' => return ([_]u8{ '\\', c })[0..],
+ '\n' => return "\\n"[0..],
+ '\r' => return "\\r"[0..],
+ '\t' => return "\\t"[0..],
+ else => {
+ var buf: [4]u8 = undefined;
+ return std.fmt.bufPrint(buf[0..], "\\x{x2}", c) catch unreachable;
+ },
+ }
+}
+
fn transCCast(
rp: RestorePoint,
scope: *Scope,