authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-17 13:37:28-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-06-17 13:37:28-07:00
log9370fb8b81f69fb28311c00f0833883acfa93521
tree54abf9602bed1373299557e56fc9fcdf9adb9117
parent366e3c657fe7d898465a0e822f1999f0572f832e
parent7ca052a6fb017882de1ebcf86226f3b2927a11c7
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14844 from perillo/fix-issue-13280

Fix issue 13280

2 files changed, 279 insertions(+), 74 deletions(-)

doc/docgen.zig+269-64
...@@ -796,28 +796,37 @@ fn writeEscaped(out: anytype, input: []const u8) !void {...@@ -796,28 +796,37 @@ fn writeEscaped(out: anytype, input: []const u8) !void {
796 }796 }
797}797}
798798
799//#define VT_RED "\x1b[31;1m"799// Returns true if number is in slice.
800//#define VT_GREEN "\x1b[32;1m"800fn in(slice: []const u8, number: u8) bool {
801//#define VT_CYAN "\x1b[36;1m"801 for (slice) |n| {
802//#define VT_WHITE "\x1b[37;1m"802 if (number == n) return true;
803//#define VT_BOLD "\x1b[0;1m"803 }
804//#define VT_RESET "\x1b[0m"804 return false;
805
806test "term color" {
807 const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";
808 const result = try termColor(std.testing.allocator, input_bytes);
809 defer std.testing.allocator.free(result);
810 try testing.expectEqualSlices(u8, "A<span class=\"t32_1\">green</span>B", result);
811}805}
812806
813fn termColor(allocator: Allocator, input: []const u8) ![]u8 {807fn termColor(allocator: Allocator, input: []const u8) ![]u8 {
808 // The SRG sequences generates by the Zig compiler are in the format:
809 // ESC [ <foreground-color> ; <n> m
810 // or
811 // ESC [ <n> m
812 //
813 // where
814 // foreground-color is 31 (red), 32 (green), 36 (cyan)
815 // n is 0 (reset), 1 (bold), 2 (dim)
816 //
817 // Note that 37 (white) is currently not used by the compiler.
818 //
819 // See std.debug.TTY.Color.
820 const supported_sgr_colors = [_]u8{ 31, 32, 36 };
821 const supported_sgr_numbers = [_]u8{ 0, 1, 2 };
822
814 var buf = std.ArrayList(u8).init(allocator);823 var buf = std.ArrayList(u8).init(allocator);
815 defer buf.deinit();824 defer buf.deinit();
816825
817 var out = buf.writer();826 var out = buf.writer();
818 var number_start_index: usize = undefined;827 var sgr_param_start_index: usize = undefined;
819 var first_number: usize = undefined;828 var sgr_num: u8 = undefined;
820 var second_number: usize = undefined;829 var sgr_color: u8 = undefined;
821 var i: usize = 0;830 var i: usize = 0;
822 var state: enum {831 var state: enum {
823 start,832 start,
...@@ -848,7 +857,7 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {...@@ -848,7 +857,7 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {
848 },857 },
849 .lbracket => switch (c) {858 .lbracket => switch (c) {
850 '0'...'9' => {859 '0'...'9' => {
851 number_start_index = i;860 sgr_param_start_index = i;
852 state = .number;861 state = .number;
853 },862 },
854 else => return error.UnsupportedEscape,863 else => return error.UnsupportedEscape,
...@@ -856,13 +865,12 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {...@@ -856,13 +865,12 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {
856 .number => switch (c) {865 .number => switch (c) {
857 '0'...'9' => {},866 '0'...'9' => {},
858 else => {867 else => {
859 first_number = std.fmt.parseInt(usize, input[number_start_index..i], 10) catch unreachable;868 sgr_num = try std.fmt.parseInt(u8, input[sgr_param_start_index..i], 10);
860 second_number = 0;869 sgr_color = 0;
861 state = .after_number;870 state = .after_number;
862 i -= 1;871 i -= 1;
863 },872 },
864 },873 },
865
866 .after_number => switch (c) {874 .after_number => switch (c) {
867 ';' => state = .arg,875 ';' => state = .arg,
868 'D' => state = .start,876 'D' => state = .start,
...@@ -877,7 +885,7 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {...@@ -877,7 +885,7 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {
877 },885 },
878 .arg => switch (c) {886 .arg => switch (c) {
879 '0'...'9' => {887 '0'...'9' => {
880 number_start_index = i;888 sgr_param_start_index = i;
881 state = .arg_number;889 state = .arg_number;
882 },890 },
883 else => return error.UnsupportedEscape,891 else => return error.UnsupportedEscape,
...@@ -885,7 +893,15 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {...@@ -885,7 +893,15 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {
885 .arg_number => switch (c) {893 .arg_number => switch (c) {
886 '0'...'9' => {},894 '0'...'9' => {},
887 else => {895 else => {
888 second_number = std.fmt.parseInt(usize, input[number_start_index..i], 10) catch unreachable;896 // Keep the sequence consistent, foreground color first.
897 // 32;1m is equivalent to 1;32m, but the latter will
898 // generate an incorrect HTML class without notice.
899 sgr_color = sgr_num;
900 if (!in(&supported_sgr_colors, sgr_color)) return error.UnsupportedForegroundColor;
901
902 sgr_num = try std.fmt.parseInt(u8, input[sgr_param_start_index..i], 10);
903 if (!in(&supported_sgr_numbers, sgr_num)) return error.UnsupportedNumber;
904
889 state = .expect_end;905 state = .expect_end;
890 i -= 1;906 i -= 1;
891 },907 },
...@@ -896,10 +912,16 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {...@@ -896,10 +912,16 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {
896 while (open_span_count != 0) : (open_span_count -= 1) {912 while (open_span_count != 0) : (open_span_count -= 1) {
897 try out.writeAll("</span>");913 try out.writeAll("</span>");
898 }914 }
899 if (first_number != 0 or second_number != 0) {915 if (sgr_num == 0) {
900 try out.print("<span class=\"t{d}_{d}\">", .{ first_number, second_number });916 if (sgr_color != 0) return error.UnsupportedColor;
901 open_span_count += 1;917 continue;
902 }918 }
919 if (sgr_color != 0) {
920 try out.print("<span class=\"sgr-{d}_{d}m\">", .{ sgr_color, sgr_num });
921 } else {
922 try out.print("<span class=\"sgr-{d}m\">", .{sgr_num});
923 }
924 open_span_count += 1;
903 },925 },
904 else => return error.UnsupportedEscape,926 else => return error.UnsupportedEscape,
905 },927 },
...@@ -1227,41 +1249,39 @@ fn printShell(out: anytype, shell_content: []const u8, escape: bool) !void {...@@ -1227,41 +1249,39 @@ fn printShell(out: anytype, shell_content: []const u8, escape: bool) !void {
1227 while (iter.next()) |orig_line| {1249 while (iter.next()) |orig_line| {
1228 const line = mem.trimRight(u8, orig_line, " ");1250 const line = mem.trimRight(u8, orig_line, " ");
1229 if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] != '\\') {1251 if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] != '\\') {
1230 try out.writeAll(start_line ++ "$ <kbd>");1252 try out.writeAll("$ <kbd>");
1231 const s = std.mem.trimLeft(u8, line[1..], " ");1253 const s = std.mem.trimLeft(u8, line[1..], " ");
1232 if (escape) {1254 if (escape) {
1233 try writeEscaped(out, s);1255 try writeEscaped(out, s);
1234 } else {1256 } else {
1235 try out.writeAll(s);1257 try out.writeAll(s);
1236 }1258 }
1237 try out.writeAll("</kbd>" ++ end_line ++ "\n");1259 try out.writeAll("</kbd>" ++ "\n");
1238 } else if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] == '\\') {1260 } else if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] == '\\') {
1239 try out.writeAll(start_line ++ "$ <kbd>");1261 try out.writeAll("$ <kbd>");
1240 const s = std.mem.trimLeft(u8, line[1..], " ");1262 const s = std.mem.trimLeft(u8, line[1..], " ");
1241 if (escape) {1263 if (escape) {
1242 try writeEscaped(out, s);1264 try writeEscaped(out, s);
1243 } else {1265 } else {
1244 try out.writeAll(s);1266 try out.writeAll(s);
1245 }1267 }
1246 try out.writeAll(end_line ++ "\n");1268 try out.writeAll("\n");
1247 cmd_cont = true;1269 cmd_cont = true;
1248 } else if (line.len > 0 and line[line.len - 1] != '\\' and cmd_cont) {1270 } else if (line.len > 0 and line[line.len - 1] != '\\' and cmd_cont) {
1249 try out.writeAll(start_line);
1250 if (escape) {1271 if (escape) {
1251 try writeEscaped(out, line);1272 try writeEscaped(out, line);
1252 } else {1273 } else {
1253 try out.writeAll(line);1274 try out.writeAll(line);
1254 }1275 }
1255 try out.writeAll("</kbd>" ++ end_line ++ "\n");1276 try out.writeAll("</kbd>" ++ "\n");
1256 cmd_cont = false;1277 cmd_cont = false;
1257 } else {1278 } else {
1258 try out.writeAll(start_line);
1259 if (escape) {1279 if (escape) {
1260 try writeEscaped(out, line);1280 try writeEscaped(out, line);
1261 } else {1281 } else {
1262 try out.writeAll(line);1282 try out.writeAll(line);
1263 }1283 }
1264 try out.writeAll(end_line ++ "\n");1284 try out.writeAll("\n");
1265 }1285 }
1266 }1286 }
12671287
...@@ -1507,7 +1527,7 @@ fn genHtml(...@@ -1507,7 +1527,7 @@ fn genHtml(
1507 const colored_stderr = try termColor(allocator, escaped_stderr);1527 const colored_stderr = try termColor(allocator, escaped_stderr);
1508 const colored_stdout = try termColor(allocator, escaped_stdout);1528 const colored_stdout = try termColor(allocator, escaped_stdout);
15091529
1510 try shell_out.print("\n$ ./{s}\n{s}{s}", .{ code.name, colored_stdout, colored_stderr });1530 try shell_out.print("$ ./{s}\n{s}{s}", .{ code.name, colored_stdout, colored_stderr });
1511 if (exited_with_signal) {1531 if (exited_with_signal) {
1512 try shell_out.print("(process terminated by signal)", .{});1532 try shell_out.print("(process terminated by signal)", .{});
1513 }1533 }
...@@ -1877,7 +1897,193 @@ fn dumpArgs(args: []const []const u8) void {...@@ -1877,7 +1897,193 @@ fn dumpArgs(args: []const []const u8) void {
1877 print("\n", .{});1897 print("\n", .{});
1878}1898}
18791899
1880test "shell parsed" {1900test "term supported colors" {
1901 const test_allocator = testing.allocator;
1902
1903 {
1904 const input = "A\x1b[31;1mred\x1b[0mB";
1905 const expect = "A<span class=\"sgr-31_1m\">red</span>B";
1906
1907 const result = try termColor(test_allocator, input);
1908 defer test_allocator.free(result);
1909 try testing.expectEqualSlices(u8, expect, result);
1910 }
1911
1912 {
1913 const input = "A\x1b[32;1mgreen\x1b[0mB";
1914 const expect = "A<span class=\"sgr-32_1m\">green</span>B";
1915
1916 const result = try termColor(test_allocator, input);
1917 defer test_allocator.free(result);
1918 try testing.expectEqualSlices(u8, expect, result);
1919 }
1920
1921 {
1922 const input = "A\x1b[36;1mcyan\x1b[0mB";
1923 const expect = "A<span class=\"sgr-36_1m\">cyan</span>B";
1924
1925 const result = try termColor(test_allocator, input);
1926 defer test_allocator.free(result);
1927 try testing.expectEqualSlices(u8, expect, result);
1928 }
1929
1930 {
1931 const input = "A\x1b[1mbold\x1b[0mB";
1932 const expect = "A<span class=\"sgr-1m\">bold</span>B";
1933
1934 const result = try termColor(test_allocator, input);
1935 defer test_allocator.free(result);
1936 try testing.expectEqualSlices(u8, expect, result);
1937 }
1938
1939 {
1940 const input = "A\x1b[2mdim\x1b[0mB";
1941 const expect = "A<span class=\"sgr-2m\">dim</span>B";
1942
1943 const result = try termColor(test_allocator, input);
1944 defer test_allocator.free(result);
1945 try testing.expectEqualSlices(u8, expect, result);
1946 }
1947}
1948
1949test "term output from zig" {
1950 // Use data generated by https://github.com/perillo/zig-tty-test-data,
1951 // with zig version 0.11.0-dev.1898+36d47dd19.
1952 const test_allocator = testing.allocator;
1953
1954 {
1955 // 1.1-with-build-progress.out
1956 const input = "Semantic Analysis [1324] \x1b[25D\x1b[0KLLVM Emit Object... \x1b[20D\x1b[0KLLVM Emit Object... \x1b[20D\x1b[0KLLD Link... \x1b[12D\x1b[0K";
1957 const expect = "";
1958
1959 const result = try termColor(test_allocator, input);
1960 defer test_allocator.free(result);
1961 try testing.expectEqualSlices(u8, expect, result);
1962 }
1963
1964 {
1965 // 2.1-with-reference-traces.out
1966 const input = "\x1b[1msrc/2.1-with-reference-traces.zig:3:7: \x1b[31;1merror: \x1b[0m\x1b[1mcannot assign to constant\n\x1b[0m x += 1;\n \x1b[32;1m~~^~~~\n\x1b[0m\x1b[0m\x1b[2mreferenced by:\n main: src/2.1-with-reference-traces.zig:7:5\n callMain: /usr/local/lib/zig/lib/std/start.zig:607:17\n remaining reference traces hidden; use '-freference-trace' to see all reference traces\n\n\x1b[0m";
1967 const expect =
1968 \\<span class="sgr-1m">src/2.1-with-reference-traces.zig:3:7: </span><span class="sgr-31_1m">error: </span><span class="sgr-1m">cannot assign to constant
1969 \\</span> x += 1;
1970 \\ <span class="sgr-32_1m">~~^~~~
1971 \\</span><span class="sgr-2m">referenced by:
1972 \\ main: src/2.1-with-reference-traces.zig:7:5
1973 \\ callMain: /usr/local/lib/zig/lib/std/start.zig:607:17
1974 \\ remaining reference traces hidden; use '-freference-trace' to see all reference traces
1975 \\
1976 \\</span>
1977 ;
1978
1979 const result = try termColor(test_allocator, input);
1980 defer test_allocator.free(result);
1981 try testing.expectEqualSlices(u8, expect, result);
1982 }
1983
1984 {
1985 // 2.2-without-reference-traces.out
1986 const input = "\x1b[1m/usr/local/lib/zig/lib/std/io/fixed_buffer_stream.zig:128:29: \x1b[31;1merror: \x1b[0m\x1b[1minvalid type given to fixedBufferStream\n\x1b[0m else => @compileError(\"invalid type given to fixedBufferStream\"),\n \x1b[32;1m^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\x1b[0m\x1b[1m/usr/local/lib/zig/lib/std/io/fixed_buffer_stream.zig:116:66: \x1b[36;1mnote: \x1b[0m\x1b[1mcalled from here\n\x1b[0mpub fn fixedBufferStream(buffer: anytype) FixedBufferStream(Slice(@TypeOf(buffer))) {\n; \x1b[32;1m~~~~~^~~~~~~~~~~~~~~~~\n\x1b[0m";
1987 const expect =
1988 \\<span class="sgr-1m">/usr/local/lib/zig/lib/std/io/fixed_buffer_stream.zig:128:29: </span><span class="sgr-31_1m">error: </span><span class="sgr-1m">invalid type given to fixedBufferStream
1989 \\</span> else => @compileError("invalid type given to fixedBufferStream"),
1990 \\ <span class="sgr-32_1m">^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1991 \\</span><span class="sgr-1m">/usr/local/lib/zig/lib/std/io/fixed_buffer_stream.zig:116:66: </span><span class="sgr-36_1m">note: </span><span class="sgr-1m">called from here
1992 \\</span>pub fn fixedBufferStream(buffer: anytype) FixedBufferStream(Slice(@TypeOf(buffer))) {
1993 \\; <span class="sgr-32_1m">~~~~~^~~~~~~~~~~~~~~~~
1994 \\</span>
1995 ;
1996
1997 const result = try termColor(test_allocator, input);
1998 defer test_allocator.free(result);
1999 try testing.expectEqualSlices(u8, expect, result);
2000 }
2001
2002 {
2003 // 2.3-with-notes.out
2004 const input = "\x1b[1msrc/2.3-with-notes.zig:6:9: \x1b[31;1merror: \x1b[0m\x1b[1mexpected type '*2.3-with-notes.Derp', found '*2.3-with-notes.Wat'\n\x1b[0m bar(w);\n \x1b[32;1m^\n\x1b[0m\x1b[1msrc/2.3-with-notes.zig:6:9: \x1b[36;1mnote: \x1b[0m\x1b[1mpointer type child '2.3-with-notes.Wat' cannot cast into pointer type child '2.3-with-notes.Derp'\n\x1b[0m\x1b[1msrc/2.3-with-notes.zig:2:13: \x1b[36;1mnote: \x1b[0m\x1b[1mopaque declared here\n\x1b[0mconst Wat = opaque {};\n \x1b[32;1m^~~~~~~~~\n\x1b[0m\x1b[1msrc/2.3-with-notes.zig:1:14: \x1b[36;1mnote: \x1b[0m\x1b[1mopaque declared here\n\x1b[0mconst Derp = opaque {};\n \x1b[32;1m^~~~~~~~~\n\x1b[0m\x1b[1msrc/2.3-with-notes.zig:4:18: \x1b[36;1mnote: \x1b[0m\x1b[1mparameter type declared here\n\x1b[0mextern fn bar(d: *Derp) void;\n \x1b[32;1m^~~~~\n\x1b[0m\x1b[0m\x1b[2mreferenced by:\n main: src/2.3-with-notes.zig:10:5\n callMain: /usr/local/lib/zig/lib/std/start.zig:607:17\n remaining reference traces hidden; use '-freference-trace' to see all reference traces\n\n\x1b[0m";
2005 const expect =
2006 \\<span class="sgr-1m">src/2.3-with-notes.zig:6:9: </span><span class="sgr-31_1m">error: </span><span class="sgr-1m">expected type '*2.3-with-notes.Derp', found '*2.3-with-notes.Wat'
2007 \\</span> bar(w);
2008 \\ <span class="sgr-32_1m">^
2009 \\</span><span class="sgr-1m">src/2.3-with-notes.zig:6:9: </span><span class="sgr-36_1m">note: </span><span class="sgr-1m">pointer type child '2.3-with-notes.Wat' cannot cast into pointer type child '2.3-with-notes.Derp'
2010 \\</span><span class="sgr-1m">src/2.3-with-notes.zig:2:13: </span><span class="sgr-36_1m">note: </span><span class="sgr-1m">opaque declared here
2011 \\</span>const Wat = opaque {};
2012 \\ <span class="sgr-32_1m">^~~~~~~~~
2013 \\</span><span class="sgr-1m">src/2.3-with-notes.zig:1:14: </span><span class="sgr-36_1m">note: </span><span class="sgr-1m">opaque declared here
2014 \\</span>const Derp = opaque {};
2015 \\ <span class="sgr-32_1m">^~~~~~~~~
2016 \\</span><span class="sgr-1m">src/2.3-with-notes.zig:4:18: </span><span class="sgr-36_1m">note: </span><span class="sgr-1m">parameter type declared here
2017 \\</span>extern fn bar(d: *Derp) void;
2018 \\ <span class="sgr-32_1m">^~~~~
2019 \\</span><span class="sgr-2m">referenced by:
2020 \\ main: src/2.3-with-notes.zig:10:5
2021 \\ callMain: /usr/local/lib/zig/lib/std/start.zig:607:17
2022 \\ remaining reference traces hidden; use '-freference-trace' to see all reference traces
2023 \\
2024 \\</span>
2025 ;
2026
2027 const result = try termColor(test_allocator, input);
2028 defer test_allocator.free(result);
2029 try testing.expectEqualSlices(u8, expect, result);
2030 }
2031
2032 {
2033 // 3.1-with-error-return-traces.out
2034
2035 const input = "error: Error\n\x1b[1m/home/zig/src/3.1-with-error-return-traces.zig:5:5\x1b[0m: \x1b[2m0x20b008 in callee (3.1-with-error-return-traces)\x1b[0m\n return error.Error;\n \x1b[32;1m^\x1b[0m\n\x1b[1m/home/zig/src/3.1-with-error-return-traces.zig:9:5\x1b[0m: \x1b[2m0x20b113 in caller (3.1-with-error-return-traces)\x1b[0m\n try callee();\n \x1b[32;1m^\x1b[0m\n\x1b[1m/home/zig/src/3.1-with-error-return-traces.zig:13:5\x1b[0m: \x1b[2m0x20b153 in main (3.1-with-error-return-traces)\x1b[0m\n try caller();\n \x1b[32;1m^\x1b[0m\n";
2036 const expect =
2037 \\error: Error
2038 \\<span class="sgr-1m">/home/zig/src/3.1-with-error-return-traces.zig:5:5</span>: <span class="sgr-2m">0x20b008 in callee (3.1-with-error-return-traces)</span>
2039 \\ return error.Error;
2040 \\ <span class="sgr-32_1m">^</span>
2041 \\<span class="sgr-1m">/home/zig/src/3.1-with-error-return-traces.zig:9:5</span>: <span class="sgr-2m">0x20b113 in caller (3.1-with-error-return-traces)</span>
2042 \\ try callee();
2043 \\ <span class="sgr-32_1m">^</span>
2044 \\<span class="sgr-1m">/home/zig/src/3.1-with-error-return-traces.zig:13:5</span>: <span class="sgr-2m">0x20b153 in main (3.1-with-error-return-traces)</span>
2045 \\ try caller();
2046 \\ <span class="sgr-32_1m">^</span>
2047 \\
2048 ;
2049
2050 const result = try termColor(test_allocator, input);
2051 defer test_allocator.free(result);
2052 try testing.expectEqualSlices(u8, expect, result);
2053 }
2054
2055 {
2056 // 3.2-with-stack-trace.out
2057 const input = "\x1b[1m/usr/local/lib/zig/lib/std/debug.zig:561:19\x1b[0m: \x1b[2m0x22a107 in writeCurrentStackTrace__anon_5898 (3.2-with-stack-trace)\x1b[0m\n while (it.next()) |return_address| {\n \x1b[32;1m^\x1b[0m\n\x1b[1m/usr/local/lib/zig/lib/std/debug.zig:157:80\x1b[0m: \x1b[2m0x20bb23 in dumpCurrentStackTrace (3.2-with-stack-trace)\x1b[0m\n writeCurrentStackTrace(stderr, debug_info, detectTTYConfig(io.getStdErr()), start_addr) catch |err| {\n \x1b[32;1m^\x1b[0m\n\x1b[1m/home/zig/src/3.2-with-stack-trace.zig:5:36\x1b[0m: \x1b[2m0x20d3b2 in foo (3.2-with-stack-trace)\x1b[0m\n std.debug.dumpCurrentStackTrace(null);\n \x1b[32;1m^\x1b[0m\n\x1b[1m/home/zig/src/3.2-with-stack-trace.zig:9:8\x1b[0m: \x1b[2m0x20b458 in main (3.2-with-stack-trace)\x1b[0m\n foo();\n \x1b[32;1m^\x1b[0m\n\x1b[1m/usr/local/lib/zig/lib/std/start.zig:607:22\x1b[0m: \x1b[2m0x20a965 in posixCallMainAndExit (3.2-with-stack-trace)\x1b[0m\n root.main();\n \x1b[32;1m^\x1b[0m\n\x1b[1m/usr/local/lib/zig/lib/std/start.zig:376:5\x1b[0m: \x1b[2m0x20a411 in _start (3.2-with-stack-trace)\x1b[0m\n @call(.never_inline, posixCallMainAndExit, .{});\n \x1b[32;1m^\x1b[0m\n";
2058 const expect =
2059 \\<span class="sgr-1m">/usr/local/lib/zig/lib/std/debug.zig:561:19</span>: <span class="sgr-2m">0x22a107 in writeCurrentStackTrace__anon_5898 (3.2-with-stack-trace)</span>
2060 \\ while (it.next()) |return_address| {
2061 \\ <span class="sgr-32_1m">^</span>
2062 \\<span class="sgr-1m">/usr/local/lib/zig/lib/std/debug.zig:157:80</span>: <span class="sgr-2m">0x20bb23 in dumpCurrentStackTrace (3.2-with-stack-trace)</span>
2063 \\ writeCurrentStackTrace(stderr, debug_info, detectTTYConfig(io.getStdErr()), start_addr) catch |err| {
2064 \\ <span class="sgr-32_1m">^</span>
2065 \\<span class="sgr-1m">/home/zig/src/3.2-with-stack-trace.zig:5:36</span>: <span class="sgr-2m">0x20d3b2 in foo (3.2-with-stack-trace)</span>
2066 \\ std.debug.dumpCurrentStackTrace(null);
2067 \\ <span class="sgr-32_1m">^</span>
2068 \\<span class="sgr-1m">/home/zig/src/3.2-with-stack-trace.zig:9:8</span>: <span class="sgr-2m">0x20b458 in main (3.2-with-stack-trace)</span>
2069 \\ foo();
2070 \\ <span class="sgr-32_1m">^</span>
2071 \\<span class="sgr-1m">/usr/local/lib/zig/lib/std/start.zig:607:22</span>: <span class="sgr-2m">0x20a965 in posixCallMainAndExit (3.2-with-stack-trace)</span>
2072 \\ root.main();
2073 \\ <span class="sgr-32_1m">^</span>
2074 \\<span class="sgr-1m">/usr/local/lib/zig/lib/std/start.zig:376:5</span>: <span class="sgr-2m">0x20a411 in _start (3.2-with-stack-trace)</span>
2075 \\ @call(.never_inline, posixCallMainAndExit, .{});
2076 \\ <span class="sgr-32_1m">^</span>
2077 \\
2078 ;
2079
2080 const result = try termColor(test_allocator, input);
2081 defer test_allocator.free(result);
2082 try testing.expectEqualSlices(u8, expect, result);
2083 }
2084}
2085
2086test "printShell" {
1881 const test_allocator = std.testing.allocator;2087 const test_allocator = std.testing.allocator;
18822088
1883 {2089 {
...@@ -1885,7 +2091,7 @@ test "shell parsed" {...@@ -1885,7 +2091,7 @@ test "shell parsed" {
1885 \\$ zig build test.zig2091 \\$ zig build test.zig
1886 ;2092 ;
1887 const expected =2093 const expected =
1888 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>2094 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1889 \\</samp></pre></figure>2095 \\</samp></pre></figure>
1890 ;2096 ;
18912097
...@@ -1893,7 +2099,6 @@ test "shell parsed" {...@@ -1893,7 +2099,6 @@ test "shell parsed" {
1893 defer buffer.deinit();2099 defer buffer.deinit();
18942100
1895 try printShell(buffer.writer(), shell_out, false);2101 try printShell(buffer.writer(), shell_out, false);
1896 std.log.emerg("{s}", .{buffer.items});
1897 try testing.expectEqualSlices(u8, expected, buffer.items);2102 try testing.expectEqualSlices(u8, expected, buffer.items);
1898 }2103 }
1899 {2104 {
...@@ -1902,8 +2107,8 @@ test "shell parsed" {...@@ -1902,8 +2107,8 @@ test "shell parsed" {
1902 \\build output2107 \\build output
1903 ;2108 ;
1904 const expected =2109 const expected =
1905 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>2110 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1906 \\<span class="line">build output</span>2111 \\build output
1907 \\</samp></pre></figure>2112 \\</samp></pre></figure>
1908 ;2113 ;
19092114
...@@ -1920,9 +2125,9 @@ test "shell parsed" {...@@ -1920,9 +2125,9 @@ test "shell parsed" {
1920 \\$ ./test2125 \\$ ./test
1921 ;2126 ;
1922 const expected =2127 const expected =
1923 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>2128 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1924 \\<span class="line">build output</span>2129 \\build output
1925 \\<span class="line">$ <kbd>./test</kbd></span>2130 \\$ <kbd>./test</kbd>
1926 \\</samp></pre></figure>2131 \\</samp></pre></figure>
1927 ;2132 ;
19282133
...@@ -1940,10 +2145,10 @@ test "shell parsed" {...@@ -1940,10 +2145,10 @@ test "shell parsed" {
1940 \\output2145 \\output
1941 ;2146 ;
1942 const expected =2147 const expected =
1943 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>2148 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1944 \\<span class="line"></span>2149 \\
1945 \\<span class="line">$ <kbd>./test</kbd></span>2150 \\$ <kbd>./test</kbd>
1946 \\<span class="line">output</span>2151 \\output
1947 \\</samp></pre></figure>2152 \\</samp></pre></figure>
1948 ;2153 ;
19492154
...@@ -1960,9 +2165,9 @@ test "shell parsed" {...@@ -1960,9 +2165,9 @@ test "shell parsed" {
1960 \\output2165 \\output
1961 ;2166 ;
1962 const expected =2167 const expected =
1963 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>2168 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1964 \\<span class="line">$ <kbd>./test</kbd></span>2169 \\$ <kbd>./test</kbd>
1965 \\<span class="line">output</span>2170 \\output
1966 \\</samp></pre></figure>2171 \\</samp></pre></figure>
1967 ;2172 ;
19682173
...@@ -1981,11 +2186,11 @@ test "shell parsed" {...@@ -1981,11 +2186,11 @@ test "shell parsed" {
1981 \\output2186 \\output
1982 ;2187 ;
1983 const expected =2188 const expected =
1984 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig \</span>2189 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \
1985 \\<span class="line"> --build-option</kbd></span>2190 \\ --build-option</kbd>
1986 \\<span class="line">build output</span>2191 \\build output
1987 \\<span class="line">$ <kbd>./test</kbd></span>2192 \\$ <kbd>./test</kbd>
1988 \\<span class="line">output</span>2193 \\output
1989 \\</samp></pre></figure>2194 \\</samp></pre></figure>
1990 ;2195 ;
19912196
...@@ -1999,15 +2204,15 @@ test "shell parsed" {...@@ -1999,15 +2204,15 @@ test "shell parsed" {
1999 // intentional space after "--build-option1 \"2204 // intentional space after "--build-option1 \"
2000 const shell_out =2205 const shell_out =
2001 \\$ zig build test.zig \2206 \\$ zig build test.zig \
2002 \\ --build-option1 \2207 \\ --build-option1 \
2003 \\ --build-option22208 \\ --build-option2
2004 \\$ ./test2209 \\$ ./test
2005 ;2210 ;
2006 const expected =2211 const expected =
2007 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig \</span>2212 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \
2008 \\<span class="line"> --build-option1 \</span>2213 \\ --build-option1 \
2009 \\<span class="line"> --build-option2</kbd></span>2214 \\ --build-option2</kbd>
2010 \\<span class="line">$ <kbd>./test</kbd></span>2215 \\$ <kbd>./test</kbd>
2011 \\</samp></pre></figure>2216 \\</samp></pre></figure>
2012 ;2217 ;
20132218
...@@ -2023,8 +2228,8 @@ test "shell parsed" {...@@ -2023,8 +2228,8 @@ test "shell parsed" {
2023 \\$ ./test2228 \\$ ./test
2024 ;2229 ;
2025 const expected =2230 const expected =
2026 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig \</span>2231 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \
2027 \\<span class="line">$ ./test</kbd></span>2232 \\$ ./test</kbd>
2028 \\</samp></pre></figure>2233 \\</samp></pre></figure>
2029 ;2234 ;
20302235
...@@ -2041,9 +2246,9 @@ test "shell parsed" {...@@ -2041,9 +2246,9 @@ test "shell parsed" {
2041 \\$12246 \\$1
2042 ;2247 ;
2043 const expected =2248 const expected =
2044 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$ <kbd>zig build test.zig</kbd></span>2249 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
2045 \\<span class="line">$ <kbd>./test</kbd></span>2250 \\$ <kbd>./test</kbd>
2046 \\<span class="line">$1</span>2251 \\$1
2047 \\</samp></pre></figure>2252 \\</samp></pre></figure>
2048 ;2253 ;
20492254
...@@ -2058,7 +2263,7 @@ test "shell parsed" {...@@ -2058,7 +2263,7 @@ test "shell parsed" {
2058 \\$zig build test.zig2263 \\$zig build test.zig
2059 ;2264 ;
2060 const expected =2265 const expected =
2061 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp><span class="line">$zig build test.zig</span>2266 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$zig build test.zig
2062 \\</samp></pre></figure>2267 \\</samp></pre></figure>
2063 ;2268 ;
20642269
doc/langref.html.in+10-10
...@@ -71,19 +71,19 @@...@@ -71,19 +71,19 @@
71 text-align: left;71 text-align: left;
72 font-weight: normal;72 font-weight: normal;
73 }73 }
74 .t0_1, .t37, .t37_1 {74 .sgr-1m {
75 font-weight: bold;75 font-weight: bold;
76 }76 }
77 .t2_0 {77 .sgr-2m {
78 color: #575757;78 color: #575757;
79 }79 }
80 .t31_1 {80 .sgr-31_1m {
81 color: #b40000;81 color: #b40000;
82 }82 }
83 .t32_1 {83 .sgr-32_1m {
84 color: green;84 color: green;
85 }85 }
86 .t36_1 {86 .sgr-36_1m {
87 color: #005C7A;87 color: #005C7A;
88 }88 }
89 .file {89 .file {
...@@ -114,7 +114,7 @@...@@ -114,7 +114,7 @@
114 line-height: normal;114 line-height: normal;
115 }115 }
116 kbd {116 kbd {
117 font-weight: bold;117 font-weight: normal;
118 }118 }
119 .table-wrapper {119 .table-wrapper {
120 width: 100%;120 width: 100%;
...@@ -232,16 +232,16 @@...@@ -232,16 +232,16 @@
232 table, th, td {232 table, th, td {
233 border-color: grey;233 border-color: grey;
234 }234 }
235 .t2_0 {235 .sgr-2m {
236 color: grey;236 color: grey;
237 }237 }
238 .t31_1 {238 .sgr-31_1m {
239 color: red;239 color: red;
240 }240 }
241 .t32_1 {241 .sgr-32_1m {
242 color: #00B800;242 color: #00B800;
243 }243 }
244 .t36_1 {244 .sgr-36_1m {
245 color: #0086b3;245 color: #0086b3;
246 }246 }
247 code {247 code {