╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ doctest.zig ──────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
1040 sgr_num = try std.fmt.parseInt(u8, input[sgr_param_start_index..i], 10); 1041 sgr_color = 0; 1042 state = .after_number; 1043 i -= 1; 1044 }, 1045 }, 1046 .after_number => switch (c) { 1047 ';' => state = .arg, 1048 'D' => state = .start, 1049 'K' => { 1050 buf.items.len = last_new_line; 1051 state = .start; 1052 }, 1053 else => { 1054 state = .expect_end; 1055 i -= 1; 1056 }, 1057 }, 1058 .arg => switch (c) { 1059 '0'...'9' => { 1060 sgr_param_start_index = i; 1061 state = .arg_number; 1062 }, 1063 else => return error.UnsupportedEscape, 1064 }, 1065 .arg_number => switch (c) { 1066 '0'...'9' => {}, 1067 else => { 1068 // Keep the sequence consistent, foreground color first. 1069 // 32;1m is equivalent to 1;32m, but the latter will 1070 // generate an incorrect HTML class without notice. 1071 sgr_color = sgr_num; 1072 if (!in(&supported_sgr_colors, sgr_color)) return error.UnsupportedForegroundColor; 1073 1074 sgr_num = try std.fmt.parseInt(u8, input[sgr_param_start_index..i], 10); 1075 if (!in(&supported_sgr_numbers, sgr_num)) return error.UnsupportedNumber; 1076 1077 state = .expect_end; 1078 i -= 1; 1079 }, 1080 }, 1081 .expect_end => switch (c) { 1082 'm' => { 1083 state = .start; 1084 while (open_span_count != 0) : (open_span_count -= 1) { 1085 try buf.appendSlice("</span>"); 1086 } 1087 if (sgr_num == 0) { 1088 if (sgr_color != 0) return error.UnsupportedColor; 1089 continue; 1090 } 1091 if (sgr_color != 0) { 1092 try buf.print("<span class=\"sgr-{d}_{d}m\">", .{ sgr_color, sgr_num }); 1093 } else { 1094 try buf.print("<span class=\"sgr-{d}m\">", .{sgr_num}); 1095 } 1096 open_span_count += 1; 1097 }, 1098 else => return error.UnsupportedEscape, 1099 }, 1100 } 1101 } 1102 return try buf.toOwnedSlice(); 1103 } 1104 1105 // Returns true if number is in slice. 1106 fn in(slice: []const u8, number: u8) bool { 1107 return mem.findScalar(u8, slice, number) != null; 1108 } 1109 1110 fn run( 1111 allocator: Allocator, 1112 io: Io, 1113 environ_map: *const process.Environ.Map, 1114 cwd: []const u8, 1115 args: []const []const u8, 1116 ) !process.RunResult { 1117 const result = try process.run(allocator, io, .{ 1118 .argv = args, 1119 .environ_map = environ_map, 1120 .cwd = .{ .path = cwd }, 1121 }); 1122 switch (result.term) { 1123 .exited => |exit_code| { 1124 if (exit_code != 0) { 1125 std.debug.print("{s}\nThe following command exited with code {}:\n", .{ result.stderr, exit_code }); 1126 dumpArgs(args); 1127 return error.ChildExitError; 1128 } 1129 }, 1130 .signal => |sig| { 1131 std.debug.print("{s}\nThe following command terminated with signal {t}:\n", .{ result.stderr, sig }); 1132 dumpArgs(args); 1133 return error.ChildCrashed; 1134 }, 1135 .stopped => |sig| { 1136 std.debug.print("{s}\nThe following command stopped with signal {t}:\n", .{ result.stderr, sig }); 1137 dumpArgs(args); 1138 return error.ChildCrashed; 1139 }, 1140 .unknown => { 1141 std.debug.print("{s}\nThe following command crashed:\n", .{result.stderr}); 1142 dumpArgs(args); 1143 return error.ChildCrashed; 1144 }, 1145 } 1146 return result; 1147 } 1148 1149 fn printShell(out: *Writer, shell_content: []const u8, escape: bool) !void { 1150 const trimmed_shell_content = mem.trim(u8, shell_content, " \r\n"); 1151 try out.writeAll("<figure><figcaption class=\"shell-cap\">Shell</figcaption><pre><samp>"); 1152 var cmd_cont: bool = false; 1153 var iter = std.mem.splitScalar(u8, trimmed_shell_content, '\n'); 1154 while (iter.next()) |orig_line| { 1155 const line = mem.trimEnd(u8, orig_line, " \r"); 1156 if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] != '\\') { 1157 try out.writeAll("$ <kbd>"); 1158 const s = std.mem.trimStart(u8, line[1..], " "); 1159 if (escape) { 1160 try writeEscaped(out, s); 1161 } else { 1162 try out.writeAll(s); 1163 } 1164 try out.writeAll("</kbd>" ++ "\n"); 1165 } else if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] == '\\') { 1166 try out.writeAll("$ <kbd>"); 1167 const s = std.mem.trimStart(u8, line[1..], " "); 1168 if (escape) { 1169 try writeEscaped(out, s); 1170 } else { 1171 try out.writeAll(s); 1172 } 1173 try out.writeAll("\n"); 1174 cmd_cont = true; 1175 } else if (line.len > 0 and line[line.len - 1] != '\\' and cmd_cont) { 1176 if (escape) { 1177 try writeEscaped(out, line); 1178 } else { 1179 try out.writeAll(line); 1180 } 1181 try out.writeAll("</kbd>" ++ "\n"); 1182 cmd_cont = false; 1183 } else { 1184 if (escape) { 1185 try writeEscaped(out, line); 1186 } else { 1187 try out.writeAll(line); 1188 } 1189 try out.writeAll("\n"); 1190 } 1191 } 1192 1193 try out.writeAll("</samp></pre></figure>"); 1194 } 1195 1196 test "term supported colors" { 1197 const test_allocator = testing.allocator; 1198 1199 { 1200 const input = "A\x1b[31;1mred\x1b[0mB"; 1201 const expect = "A<span class=\"sgr-31_1m\">red</span>B"; 1202 1203 const result = try termColor(test_allocator, input); 1204 defer test_allocator.free(result); 1205 try testing.expectEqualSlices(u8, expect, result); 1206 } 1207 1208 { 1209 const input = "A\x1b[32;1mgreen\x1b[0mB"; 1210 const expect = "A<span class=\"sgr-32_1m\">green</span>B"; 1211 1212 const result = try termColor(test_allocator, input); 1213 defer test_allocator.free(result); 1214 try testing.expectEqualSlices(u8, expect, result); 1215 } 1216 1217 { 1218 const input = "A\x1b[36;1mcyan\x1b[0mB"; 1219 const expect = "A<span class=\"sgr-36_1m\">cyan</span>B"; 1220 1221 const result = try termColor(test_allocator, input); 1222 defer test_allocator.free(result); 1223 try testing.expectEqualSlices(u8, expect, result); 1224 } 1225 1226 { 1227 const input = "A\x1b[1mbold\x1b[0mB"; 1228 const expect = "A<span class=\"sgr-1m\">bold</span>B"; 1229 1230 const result = try termColor(test_allocator, input); 1231 defer test_allocator.free(result); 1232 try testing.expectEqualSlices(u8, expect, result); 1233 } 1234 1235 { 1236 const input = "A\x1b[2mdim\x1b[0mB"; 1237 const expect = "A<span class=\"sgr-2m\">dim</span>B"; 1238 1239 const result = try termColor(test_allocator, input); 1240 defer test_allocator.free(result); 1241 try testing.expectEqualSlices(u8, expect, result); 1242 } 1243 } 1244 1245 test "term output from zig" { 1246 // Use data generated by https://github.com/perillo/zig-tty-test-data, 1247 // with zig version 0.11.0-dev.1898+36d47dd19. 1248 const test_allocator = testing.allocator; 1249 1250 { 1251 // 1.1-with-build-progress.out 1252 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"; 1253 const expect = ""; 1254 1255 const result = try termColor(test_allocator, input); 1256 defer test_allocator.free(result); 1257 try testing.expectEqualSlices(u8, expect, result); 1258 } 1259 1260 { 1261 // 2.1-with-reference-traces.out 1262 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"; 1263 const expect = 1264 \\<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 1265 \\</span> x += 1; 1266 \\ <span class="sgr-32_1m">~~^~~~ 1267 \\</span><span class="sgr-2m">referenced by: 1268 \\ main: src/2.1-with-reference-traces.zig:7:5 1269 \\ callMain: /usr/local/lib/zig/lib/std/start.zig:607:17 1270 \\ remaining reference traces hidden; use '-freference-trace' to see all reference traces 1271 \\ 1272 \\</span> 1273 ; 1274 1275 const result = try termColor(test_allocator, input); 1276 defer test_allocator.free(result); 1277 try testing.expectEqualSlices(u8, expect, result); 1278 } 1279 1280 { 1281 // 2.2-without-reference-traces.out 1282 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"; 1283 const expect = 1284 \\<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 1285 \\</span> else => @compileError("invalid type given to fixedBufferStream"), 1286 \\ <span class="sgr-32_1m">^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1287 \\</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 1288 \\</span>pub fn fixedBufferStream(buffer: anytype) FixedBufferStream(Slice(@TypeOf(buffer))) { 1289 \\; <span class="sgr-32_1m">~~~~~^~~~~~~~~~~~~~~~~ 1290 \\</span> 1291 ; 1292 1293 const result = try termColor(test_allocator, input); 1294 defer test_allocator.free(result); 1295 try testing.expectEqualSlices(u8, expect, result); 1296 } 1297 1298 { 1299 // 2.3-with-notes.out 1300 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"; 1301 const expect = 1302 \\<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' 1303 \\</span> bar(w); 1304 \\ <span class="sgr-32_1m">^ 1305 \\</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' 1306 \\</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 1307 \\</span>const Wat = opaque {}; 1308 \\ <span class="sgr-32_1m">^~~~~~~~~ 1309 \\</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 1310 \\</span>const Derp = opaque {}; 1311 \\ <span class="sgr-32_1m">^~~~~~~~~ 1312 \\</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 1313 \\</span>extern fn bar(d: *Derp) void; 1314 \\ <span class="sgr-32_1m">^~~~~ 1315 \\</span><span class="sgr-2m">referenced by: 1316 \\ main: src/2.3-with-notes.zig:10:5 1317 \\ callMain: /usr/local/lib/zig/lib/std/start.zig:607:17 1318 \\ remaining reference traces hidden; use '-freference-trace' to see all reference traces 1319 \\ 1320 \\</span> 1321 ; 1322 1323 const result = try termColor(test_allocator, input); 1324 defer test_allocator.free(result); 1325 try testing.expectEqualSlices(u8, expect, result); 1326 } 1327 1328 { 1329 // 3.1-with-error-return-traces.out 1330 1331 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"; 1332 const expect = 1333 \\error: Error 1334 \\<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> 1335 \\ return error.Error; 1336 \\ <span class="sgr-32_1m">^</span> 1337 \\<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> 1338 \\ try callee(); 1339 \\ <span class="sgr-32_1m">^</span> 1340 \\<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> 1341 \\ try caller(); 1342 \\ <span class="sgr-32_1m">^</span> 1343 \\ 1344 ; 1345 1346 const result = try termColor(test_allocator, input); 1347 defer test_allocator.free(result); 1348 try testing.expectEqualSlices(u8, expect, result); 1349 } 1350 1351 { 1352 // 3.2-with-stack-trace.out 1353 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"; 1354 const expect = 1355 \\<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> 1356 \\ while (it.next()) |return_address| { 1357 \\ <span class="sgr-32_1m">^</span> 1358 \\<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> 1359 \\ writeCurrentStackTrace(stderr, debug_info, detectTTYConfig(io.getStdErr()), start_addr) catch |err| { 1360 \\ <span class="sgr-32_1m">^</span> 1361 \\<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> 1362 \\ std.debug.dumpCurrentStackTrace(null); 1363 \\ <span class="sgr-32_1m">^</span> 1364 \\<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> 1365 \\ foo(); 1366 \\ <span class="sgr-32_1m">^</span> 1367 \\<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> 1368 \\ root.main(); 1369 \\ <span class="sgr-32_1m">^</span> 1370 \\<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> 1371 \\ @call(.never_inline, posixCallMainAndExit, .{}); 1372 \\ <span class="sgr-32_1m">^</span> 1373 \\ 1374 ; 1375 1376 const result = try termColor(test_allocator, input); 1377 defer test_allocator.free(result); 1378 try testing.expectEqualSlices(u8, expect, result); 1379 } 1380 } 1381 1382 test "printShell" { 1383 const test_allocator = std.testing.allocator; 1384 1385 { 1386 const shell_out = 1387 \\$ zig build test.zig 1388 ; 1389 const expected = 1390 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> 1391 \\</samp></pre></figure> 1392 ; 1393 1394 var buffer: Writer.Allocating = .init(test_allocator); 1395 defer buffer.deinit(); 1396 1397 try printShell(&buffer.writer, shell_out, false); 1398 try testing.expectEqualSlices(u8, expected, buffer.written()); 1399 } 1400 { 1401 const shell_out = 1402 \\$ zig build test.zig 1403 \\build output 1404 ; 1405 const expected = 1406 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> 1407 \\build output 1408 \\</samp></pre></figure> 1409 ; 1410 1411 var buffer: Writer.Allocating = .init(test_allocator); 1412 defer buffer.deinit(); 1413 1414 try printShell(&buffer.writer, shell_out, false); 1415 try testing.expectEqualSlices(u8, expected, buffer.written()); 1416 } 1417 { 1418 const shell_out = "$ zig build test.zig\r\nbuild output\r\n"; 1419 const expected = 1420 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> 1421 \\build output 1422 \\</samp></pre></figure> 1423 ; 1424 1425 var buffer: Writer.Allocating = .init(test_allocator); 1426 defer buffer.deinit(); 1427 1428 try printShell(&buffer.writer, shell_out, false); 1429 try testing.expectEqualSlices(u8, expected, buffer.written()); 1430 } 1431 { 1432 const shell_out = 1433 \\$ zig build test.zig 1434 \\build output 1435 \\$ ./test 1436 ; 1437 const expected = 1438 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> 1439 \\build output 1440 \\$ <kbd>./test</kbd> 1441 \\</samp></pre></figure> 1442 ; 1443 1444 var buffer: Writer.Allocating = .init(test_allocator); 1445 defer buffer.deinit(); 1446 1447 try printShell(&buffer.writer, shell_out, false); 1448 try testing.expectEqualSlices(u8, expected, buffer.written()); 1449 } 1450 { 1451 const shell_out = 1452 \\$ zig build test.zig 1453 \\ 1454 \\$ ./test 1455 \\output 1456 ; 1457 const expected = 1458 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> 1459 \\ 1460 \\$ <kbd>./test</kbd> 1461 \\output 1462 \\</samp></pre></figure> 1463 ; 1464 1465 var buffer: Writer.Allocating = .init(test_allocator); 1466 defer buffer.deinit(); 1467 1468 try printShell(&buffer.writer, shell_out, false); 1469 try testing.expectEqualSlices(u8, expected, buffer.written()); 1470 } 1471 { 1472 const shell_out = 1473 \\$ zig build test.zig 1474 \\$ ./test 1475 \\output 1476 ; 1477 const expected = 1478 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> 1479 \\$ <kbd>./test</kbd> 1480 \\output 1481 \\</samp></pre></figure> 1482 ; 1483 1484 var buffer: Writer.Allocating = .init(test_allocator); 1485 defer buffer.deinit(); 1486 1487 try printShell(&buffer.writer, shell_out, false); 1488 try testing.expectEqualSlices(u8, expected, buffer.written()); 1489 } 1490 { 1491 const shell_out = 1492 \\$ zig build test.zig \ 1493 \\ --build-option 1494 \\build output 1495 \\$ ./test 1496 \\output 1497 ; 1498 const expected = 1499 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \ 1500 \\ --build-option</kbd> 1501 \\build output 1502 \\$ <kbd>./test</kbd> 1503 \\output 1504 \\</samp></pre></figure> 1505 ; 1506 1507 var buffer: Writer.Allocating = .init(test_allocator); 1508 defer buffer.deinit(); 1509 1510 try printShell(&buffer.writer, shell_out, false); 1511 try testing.expectEqualSlices(u8, expected, buffer.written()); 1512 } 1513 { 1514 // intentional space after "--build-option1 \" 1515 const shell_out = 1516 \\$ zig build test.zig \ 1517 \\ --build-option1 \ 1518 \\ --build-option2 1519 \\$ ./test 1520 ; 1521 const expected = 1522 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \ 1523 \\ --build-option1 \ 1524 \\ --build-option2</kbd> 1525 \\$ <kbd>./test</kbd> 1526 \\</samp></pre></figure> 1527 ; 1528 1529 var buffer: Writer.Allocating = .init(test_allocator); 1530 defer buffer.deinit(); 1531 1532 try printShell(&buffer.writer, shell_out, false); 1533 try testing.expectEqualSlices(u8, expected, buffer.written()); 1534 } 1535 { 1536 const shell_out = 1537 \\$ zig build test.zig \ 1538 \\$ ./test 1539 ; 1540 const expected = 1541 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \ 1542 \\$ ./test</kbd> 1543 \\</samp></pre></figure> 1544 ; 1545 1546 var buffer: Writer.Allocating = .init(test_allocator); 1547 defer buffer.deinit(); 1548 1549 try printShell(&buffer.writer, shell_out, false); 1550 try testing.expectEqualSlices(u8, expected, buffer.written()); 1551 } 1552 { 1553 const shell_out = 1554 \\$ zig build test.zig 1555 \\$ ./test 1556 \\$1 1557 ; 1558 const expected = 1559 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd> 1560 \\$ <kbd>./test</kbd> 1561 \\$1 1562 \\</samp></pre></figure> 1563 ; 1564 1565 var buffer: Writer.Allocating = .init(test_allocator); 1566 defer buffer.deinit(); 1567 1568 try printShell(&buffer.writer, shell_out, false); 1569 try testing.expectEqualSlices(u8, expected, buffer.written()); 1570 } 1571 { 1572 const shell_out = 1573 \\$zig build test.zig 1574 ; 1575 const expected = 1576 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$zig build test.zig 1577 \\</samp></pre></figure> 1578 ; 1579 1580 var buffer: Writer.Allocating = .init(test_allocator); 1581 defer buffer.deinit(); 1582 1583 try printShell(&buffer.writer, shell_out, false); 1584 try testing.expectEqualSlices(u8, expected, buffer.written()); 1585 } 1586 } 1587