| ... | ... | @@ -678,10 +678,20 @@ fn transStringLiteral( |
| 678 | 678 | const kind = ZigClangStringLiteral_getKind(stmt); |
| 679 | 679 | switch (kind) { |
| 680 | 680 | .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); |
| 683 | 683 | 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); |
| 685 | 695 | const node = try rp.c.a().create(ast.Node.StringLiteral); |
| 686 | 696 | node.* = ast.Node.StringLiteral{ |
| 687 | 697 | .base = ast.Node{ .id = .StringLiteral }, |
| ... | ... | @@ -704,6 +714,37 @@ fn transStringLiteral( |
| 704 | 714 | } |
| 705 | 715 | } |
| 706 | 716 | |
| 717 | fn escapedStringLen(s: []const u8) usize { |
| 718 | var len: usize = 0; |
| 719 | for (s) |c| len += escapeChar(c).len; |
| 720 | return len; |
| 721 | } |
| 722 | |
| 723 | fn 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 | |
| 732 | fn 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 | |
| 707 | 748 | fn transCCast( |
| 708 | 749 | rp: RestorePoint, |
| 709 | 750 | scope: *Scope, |