authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-06-30 10:15:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-07 22:43:51-07:00
log1d763c8b29360a5f3b52747231876b54db1c7ba0
treec8092a1dc9675797310567ee61c9f20e0dfc906a
parent7eae26d60895dc62fa62f6562a4eeecb8685aae5

std: formatted printing no longer prints type names

for structs, enums, and unions. auto untagged unions are no longer printed as pointers; instead they are printed as "{ ... }". extern and packed untagged unions have each field printed, similar to what gdb does. also fix bugs in delimiter based reading

4 files changed, 177 insertions(+), 128 deletions(-)

lib/std/fmt.zig+26-31
......@@ -996,7 +996,7 @@ test "slice" {
996996 x: u8,
997997 };
998998 const struct_slice: []const S1 = &[_]S1{ S1{ .x = 8 }, S1{ .x = 42 } };
999 try expectFmt("slice: { fmt.test.slice.S1{ .x = 8 }, fmt.test.slice.S1{ .x = 42 } }", "slice: {any}", .{struct_slice});
999 try expectFmt("slice: { .{ .x = 8 }, .{ .x = 42 } }", "slice: {any}", .{struct_slice});
10001000 }
10011001 {
10021002 const S2 = struct {
......@@ -1007,7 +1007,7 @@ test "slice" {
10071007 }
10081008 };
10091009 const struct_slice: []const S2 = &[_]S2{ S2{ .x = 8 }, S2{ .x = 42 } };
1010 try expectFmt("slice: { fmt.test.slice.S2{ .x = 8 }, fmt.test.slice.S2{ .x = 42 } }", "slice: {any}", .{struct_slice});
1010 try expectFmt("slice: { .{ .x = 8 }, .{ .x = 42 } }", "slice: {any}", .{struct_slice});
10111011 }
10121012}
10131013
......@@ -1047,8 +1047,8 @@ test "struct" {
10471047 field: u8,
10481048 };
10491049 const value = Struct{ .field = 42 };
1050 try expectFmt("struct: fmt.test.struct.Struct{ .field = 42 }\n", "struct: {}\n", .{value});
1051 try expectFmt("struct: fmt.test.struct.Struct{ .field = 42 }\n", "struct: {}\n", .{&value});
1050 try expectFmt("struct: .{ .field = 42 }\n", "struct: {}\n", .{value});
1051 try expectFmt("struct: .{ .field = 42 }\n", "struct: {}\n", .{&value});
10521052 }
10531053 {
10541054 const Struct = struct {
......@@ -1056,7 +1056,7 @@ test "struct" {
10561056 b: u1,
10571057 };
10581058 const value = Struct{ .a = 0, .b = 1 };
1059 try expectFmt("struct: fmt.test.struct.Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
1059 try expectFmt("struct: .{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
10601060 }
10611061
10621062 const S = struct {
......@@ -1069,11 +1069,11 @@ test "struct" {
10691069 .b = error.Unused,
10701070 };
10711071
1072 try expectFmt("fmt.test.struct.S{ .a = 456, .b = error.Unused }", "{}", .{inst});
1072 try expectFmt(".{ .a = 456, .b = error.Unused }", "{}", .{inst});
10731073 // Tuples
1074 try expectFmt("{ }", "{}", .{.{}});
1075 try expectFmt("{ -1 }", "{}", .{.{-1}});
1076 try expectFmt("{ -1, 42, 25000 }", "{}", .{.{ -1, 42, 0.25e5 }});
1074 try expectFmt(".{ }", "{}", .{.{}});
1075 try expectFmt(".{ -1 }", "{}", .{.{-1}});
1076 try expectFmt(".{ -1, 42, 25000 }", "{}", .{.{ -1, 42, 0.25e5 }});
10771077}
10781078
10791079test "enum" {
......@@ -1082,15 +1082,15 @@ test "enum" {
10821082 Two,
10831083 };
10841084 const value = Enum.Two;
1085 try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{value});
1086 try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{&value});
1087 try expectFmt("enum: fmt.test.enum.Enum.One\n", "enum: {}\n", .{Enum.One});
1088 try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{Enum.Two});
1085 try expectFmt("enum: .Two\n", "enum: {}\n", .{value});
1086 try expectFmt("enum: .Two\n", "enum: {}\n", .{&value});
1087 try expectFmt("enum: .One\n", "enum: {}\n", .{Enum.One});
1088 try expectFmt("enum: .Two\n", "enum: {}\n", .{Enum.Two});
10891089
10901090 // test very large enum to verify ct branch quota is large enough
10911091 // TODO: https://github.com/ziglang/zig/issues/15609
10921092 if (!((builtin.cpu.arch == .wasm32) and builtin.mode == .Debug)) {
1093 try expectFmt("enum: os.windows.win32error.Win32Error.INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
1093 try expectFmt("enum: .INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
10941094 }
10951095
10961096 const E = enum {
......@@ -1101,7 +1101,7 @@ test "enum" {
11011101
11021102 const inst = E.Two;
11031103
1104 try expectFmt("fmt.test.enum.E.Two", "{}", .{inst});
1104 try expectFmt(".Two", "{}", .{inst});
11051105}
11061106
11071107test "non-exhaustive enum" {
......@@ -1110,9 +1110,9 @@ test "non-exhaustive enum" {
11101110 Two = 0xbeef,
11111111 _,
11121112 };
1113 try expectFmt("enum: fmt.test.non-exhaustive enum.Enum.One\n", "enum: {}\n", .{Enum.One});
1114 try expectFmt("enum: fmt.test.non-exhaustive enum.Enum.Two\n", "enum: {}\n", .{Enum.Two});
1115 try expectFmt("enum: fmt.test.non-exhaustive enum.Enum(4660)\n", "enum: {}\n", .{@as(Enum, @enumFromInt(0x1234))});
1113 try expectFmt("enum: .One\n", "enum: {}\n", .{Enum.One});
1114 try expectFmt("enum: .Two\n", "enum: {}\n", .{Enum.Two});
1115 try expectFmt("enum: @enumFromInt(4660)\n", "enum: {}\n", .{@as(Enum, @enumFromInt(0x1234))});
11161116 try expectFmt("enum: f\n", "enum: {x}\n", .{Enum.One});
11171117 try expectFmt("enum: beef\n", "enum: {x}\n", .{Enum.Two});
11181118 try expectFmt("enum: BEEF\n", "enum: {X}\n", .{Enum.Two});
......@@ -1291,18 +1291,13 @@ test "union" {
12911291 int: u32,
12921292 };
12931293
1294 const tu_inst = TU{ .int = 123 };
1295 const uu_inst = UU{ .int = 456 };
1296 const eu_inst = EU{ .float = 321.123 };
1294 const tu_inst: TU = .{ .int = 123 };
1295 const uu_inst: UU = .{ .int = 456 };
1296 const eu_inst: EU = .{ .float = 321.123 };
12971297
1298 try expectFmt("fmt.test.union.TU{ .int = 123 }", "{}", .{tu_inst});
1299
1300 var buf: [100]u8 = undefined;
1301 const uu_result = try bufPrint(buf[0..], "{}", .{uu_inst});
1302 try std.testing.expectEqualStrings("fmt.test.union.UU@", uu_result[0..18]);
1303
1304 const eu_result = try bufPrint(buf[0..], "{}", .{eu_inst});
1305 try std.testing.expectEqualStrings("fmt.test.union.EU@", eu_result[0..18]);
1298 try expectFmt(".{ .int = 123 }", "{}", .{tu_inst});
1299 try expectFmt(".{ ... }", "{}", .{uu_inst});
1300 try expectFmt(".{ .float = 321.123, .int = 1134596030 }", "{}", .{eu_inst});
13061301}
13071302
13081303test "struct.self-referential" {
......@@ -1316,7 +1311,7 @@ test "struct.self-referential" {
13161311 };
13171312 inst.a = &inst;
13181313
1319 try expectFmt("fmt.test.struct.self-referential.S{ .a = fmt.test.struct.self-referential.S{ .a = fmt.test.struct.self-referential.S{ .a = fmt.test.struct.self-referential.S{ ... } } } }", "{}", .{inst});
1314 try expectFmt(".{ .a = .{ .a = .{ .a = .{ ... } } } }", "{}", .{inst});
13201315}
13211316
13221317test "struct.zero-size" {
......@@ -1331,7 +1326,7 @@ test "struct.zero-size" {
13311326 const a = A{};
13321327 const b = B{ .a = a, .c = 0 };
13331328
1334 try expectFmt("fmt.test.struct.zero-size.B{ .a = fmt.test.struct.zero-size.A{ }, .c = 0 }", "{}", .{b});
1329 try expectFmt(".{ .a = .{ }, .c = 0 }", "{}", .{b});
13351330}
13361331
13371332/// Encodes a sequence of bytes as hexadecimal digits.
lib/std/io/Reader.zig+108-38
......@@ -36,7 +36,10 @@ pub const VTable = struct {
3636 /// sizes combined with short reads (returning a value less than `limit`)
3737 /// in order to minimize complexity.
3838 ///
39 /// This function is always called when `buffer` is empty.
39 /// Although this function is usually called when `buffer` is empty, it is
40 /// also called when it needs to be filled more due to the API user
41 /// requesting contiguous memory. In either case, the existing buffer data
42 /// should be ignored; new data written to `w`.
4043 stream: *const fn (r: *Reader, w: *Writer, limit: Limit) StreamError!usize,
4144
4245 /// Consumes bytes from the internally tracked stream position without
......@@ -194,7 +197,7 @@ pub fn streamRemaining(r: *Reader, w: *Writer) StreamRemainingError!usize {
194197/// Consumes the stream until the end, ignoring all the data, returning the
195198/// number of bytes discarded.
196199pub fn discardRemaining(r: *Reader) ShortError!usize {
197 var offset: usize = r.end;
200 var offset: usize = r.end - r.seek;
198201 r.seek = 0;
199202 r.end = 0;
200203 while (true) {
......@@ -693,6 +696,17 @@ pub fn takeSentinel(r: *Reader, comptime sentinel: u8) DelimiterError![:sentinel
693696 return result;
694697}
695698
699/// Returns a slice of the next bytes of buffered data from the stream until
700/// `sentinel` is found, without advancing the seek position.
701///
702/// Returned slice has a sentinel; end of stream does not count as a delimiter.
703///
704/// Invalidates previously returned values from `peek`.
705///
706/// See also:
707/// * `takeSentinel`
708/// * `peekDelimiterExclusive`
709/// * `peekDelimiterInclusive`
696710pub fn peekSentinel(r: *Reader, comptime sentinel: u8) DelimiterError![:sentinel]u8 {
697711 const result = try r.peekDelimiterInclusive(sentinel);
698712 return result[0 .. result.len - 1 :sentinel];
......@@ -733,27 +747,37 @@ pub fn peekDelimiterInclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
733747 @branchHint(.likely);
734748 return buffer[seek .. end + 1];
735749 }
736 if (seek > 0) {
737 const remainder = buffer[seek..];
738 @memmove(buffer[0..remainder.len], remainder);
739 r.end = remainder.len;
740 r.seek = 0;
750 while (r.buffer.len - r.end != 0) {
751 const end_cap = r.buffer[r.end..];
752 var writer: Writer = .fixed(end_cap);
753 const n = r.vtable.stream(r, &writer, .limited(end_cap.len)) catch |err| switch (err) {
754 error.WriteFailed => unreachable,
755 else => |e| return e,
756 };
757 r.end += n;
758 if (std.mem.indexOfScalarPos(u8, end_cap[0..n], 0, delimiter)) |end| {
759 return r.buffer[seek .. r.end - n + end + 1];
760 }
741761 }
742 var writer: Writer = .{
743 .buffer = r.buffer,
744 .vtable = &.{ .drain = Writer.fixedDrain },
745 };
746 while (r.end < r.buffer.len) {
747 writer.end = r.end;
748 const n = r.vtable.stream(r, &writer, .limited(r.buffer.len - r.end)) catch |err| switch (err) {
762 var i: usize = 0;
763 while (seek - i != 0) {
764 const begin_cap = r.buffer[i..seek];
765 var writer: Writer = .fixed(begin_cap);
766 const n = r.vtable.stream(r, &writer, .limited(begin_cap.len)) catch |err| switch (err) {
749767 error.WriteFailed => unreachable,
750768 else => |e| return e,
751769 };
752 const prev_end = r.end;
753 r.end = prev_end + n;
754 if (std.mem.indexOfScalarPos(u8, r.buffer[0..r.end], prev_end, delimiter)) |end| {
755 return r.buffer[0 .. end + 1];
770 i += n;
771 if (std.mem.indexOfScalarPos(u8, r.buffer[0..seek], i, delimiter)) |end| {
772 std.mem.rotate(u8, r.buffer, seek);
773 r.seek = 0;
774 r.end += i;
775 return r.buffer[0 .. seek + end + 1];
756776 }
777 } else if (i != 0) {
778 std.mem.rotate(u8, r.buffer, seek);
779 r.seek = 0;
780 r.end += i;
757781 }
758782 return error.StreamTooLong;
759783}
......@@ -778,9 +802,10 @@ pub fn peekDelimiterInclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
778802pub fn takeDelimiterExclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
779803 const result = r.peekDelimiterInclusive(delimiter) catch |err| switch (err) {
780804 error.EndOfStream => {
781 if (r.end == 0) return error.EndOfStream;
782 r.toss(r.end);
783 return r.buffer[0..r.end];
805 const remaining = r.buffer[r.seek..r.end];
806 if (remaining.len == 0) return error.EndOfStream;
807 r.toss(remaining.len);
808 return remaining;
784809 },
785810 else => |e| return e,
786811 };
......@@ -808,8 +833,10 @@ pub fn takeDelimiterExclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
808833pub fn peekDelimiterExclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
809834 const result = r.peekDelimiterInclusive(delimiter) catch |err| switch (err) {
810835 error.EndOfStream => {
811 if (r.end == 0) return error.EndOfStream;
812 return r.buffer[0..r.end];
836 const remaining = r.buffer[r.seek..r.end];
837 if (remaining.len == 0) return error.EndOfStream;
838 r.toss(remaining.len);
839 return remaining;
813840 },
814841 else => |e| return e,
815842 };
......@@ -1219,27 +1246,38 @@ test fixed {
12191246}
12201247
12211248test peek {
1222 return error.Unimplemented;
1249 var r: Reader = .fixed("abc");
1250 try testing.expectEqualStrings("ab", try r.peek(2));
1251 try testing.expectEqualStrings("a", try r.peek(1));
12231252}
12241253
12251254test peekGreedy {
1226 return error.Unimplemented;
1255 var r: Reader = .fixed("abc");
1256 try testing.expectEqualStrings("abc", try r.peekGreedy(1));
12271257}
12281258
12291259test toss {
1230 return error.Unimplemented;
1260 var r: Reader = .fixed("abc");
1261 r.toss(1);
1262 try testing.expectEqualStrings("bc", r.buffered());
12311263}
12321264
12331265test take {
1234 return error.Unimplemented;
1266 var r: Reader = .fixed("abc");
1267 try testing.expectEqualStrings("ab", try r.take(2));
1268 try testing.expectEqualStrings("c", try r.take(1));
12351269}
12361270
12371271test takeArray {
1238 return error.Unimplemented;
1272 var r: Reader = .fixed("abc");
1273 try testing.expectEqualStrings("ab", try r.takeArray(2));
1274 try testing.expectEqualStrings("c", try r.takeArray(1));
12391275}
12401276
12411277test peekArray {
1242 return error.Unimplemented;
1278 var r: Reader = .fixed("abc");
1279 try testing.expectEqualStrings("ab", try r.peekArray(2));
1280 try testing.expectEqualStrings("a", try r.peekArray(1));
12431281}
12441282
12451283test discardAll {
......@@ -1251,35 +1289,63 @@ test discardAll {
12511289}
12521290
12531291test discardRemaining {
1254 return error.Unimplemented;
1292 var r: Reader = .fixed("foobar");
1293 r.toss(1);
1294 try testing.expectEqual(5, try r.discardRemaining());
1295 try testing.expectEqual(0, try r.discardRemaining());
12551296}
12561297
12571298test stream {
1258 return error.Unimplemented;
1299 var out_buffer: [10]u8 = undefined;
1300 var r: Reader = .fixed("foobar");
1301 var w: Writer = .fixed(&out_buffer);
1302 // Short streams are possible with this function but not with fixed.
1303 try testing.expectEqual(2, try r.stream(&w, .limited(2)));
1304 try testing.expectEqualStrings("fo", w.buffered());
1305 try testing.expectEqual(4, try r.stream(&w, .unlimited));
1306 try testing.expectEqualStrings("foobar", w.buffered());
12591307}
12601308
12611309test takeSentinel {
1262 return error.Unimplemented;
1310 var r: Reader = .fixed("ab\nc");
1311 try testing.expectEqualStrings("ab", try r.takeSentinel('\n'));
1312 try testing.expectError(error.EndOfStream, r.takeSentinel('\n'));
1313 try testing.expectEqualStrings("c", try r.peek(1));
12631314}
12641315
12651316test peekSentinel {
1266 return error.Unimplemented;
1317 var r: Reader = .fixed("ab\nc");
1318 try testing.expectEqualStrings("ab", try r.peekSentinel('\n'));
1319 try testing.expectEqualStrings("ab", try r.peekSentinel('\n'));
12671320}
12681321
12691322test takeDelimiterInclusive {
1270 return error.Unimplemented;
1323 var r: Reader = .fixed("ab\nc");
1324 try testing.expectEqualStrings("ab\n", try r.takeDelimiterInclusive('\n'));
1325 try testing.expectError(error.EndOfStream, r.takeDelimiterInclusive('\n'));
12711326}
12721327
12731328test peekDelimiterInclusive {
1274 return error.Unimplemented;
1329 var r: Reader = .fixed("ab\nc");
1330 try testing.expectEqualStrings("ab\n", try r.peekDelimiterInclusive('\n'));
1331 try testing.expectEqualStrings("ab\n", try r.peekDelimiterInclusive('\n'));
1332 r.toss(3);
1333 try testing.expectError(error.EndOfStream, r.peekDelimiterInclusive('\n'));
12751334}
12761335
12771336test takeDelimiterExclusive {
1278 return error.Unimplemented;
1337 var r: Reader = .fixed("ab\nc");
1338 try testing.expectEqualStrings("ab", try r.takeDelimiterExclusive('\n'));
1339 try testing.expectEqualStrings("c", try r.takeDelimiterExclusive('\n'));
1340 try testing.expectError(error.EndOfStream, r.takeDelimiterExclusive('\n'));
12791341}
12801342
12811343test peekDelimiterExclusive {
1282 return error.Unimplemented;
1344 var r: Reader = .fixed("ab\nc");
1345 try testing.expectEqualStrings("ab", try r.peekDelimiterExclusive('\n'));
1346 try testing.expectEqualStrings("ab", try r.peekDelimiterExclusive('\n'));
1347 r.toss(3);
1348 try testing.expectEqualStrings("c", try r.peekDelimiterExclusive('\n'));
12831349}
12841350
12851351test readDelimiter {
......@@ -1339,7 +1405,11 @@ test peekStructEndian {
13391405}
13401406
13411407test takeEnum {
1342 return error.Unimplemented;
1408 var r: Reader = .fixed(&.{ 2, 0, 1 });
1409 const E1 = enum(u8) { a, b, c };
1410 const E2 = enum(u16) { _ };
1411 try testing.expectEqual(E1.c, try r.takeEnum(E1, .little));
1412 try testing.expectEqual(@as(E2, @enumFromInt(0x0001)), try r.takeEnum(E2, .big));
13431413}
13441414
13451415test takeLeb128 {
lib/std/io/Writer.zig+34-26
......@@ -866,35 +866,31 @@ pub fn printValue(
866866 }
867867 const enum_info = @typeInfo(T).@"enum";
868868 if (enum_info.is_exhaustive) {
869 var vecs: [3][]const u8 = .{ @typeName(T), ".", @tagName(value) };
869 var vecs: [2][]const u8 = .{ ".", @tagName(value) };
870870 try w.writeVecAll(&vecs);
871871 return;
872872 }
873 try w.writeAll(@typeName(T));
874 @setEvalBranchQuota(3 * enum_info.fields.len);
875 inline for (enum_info.fields) |field| {
876 if (@intFromEnum(value) == field.value) {
877 try w.writeAll(".");
878 try w.writeAll(@tagName(value));
879 return;
880 }
873 if (std.enums.tagName(T, value)) |tag_name| {
874 var vecs: [2][]const u8 = .{ ".", tag_name };
875 try w.writeVecAll(&vecs);
876 return;
881877 }
882 try w.writeByte('(');
878 try w.writeAll("@enumFromInt(");
883879 try w.printValue(ANY, options, @intFromEnum(value), max_depth);
884880 try w.writeByte(')');
881 return;
885882 },
886883 .@"union" => |info| {
887884 if (!is_any) {
888885 if (fmt.len != 0) invalidFmtError(fmt, value);
889886 return printValue(w, ANY, options, value, max_depth);
890887 }
891 try w.writeAll(@typeName(T));
892888 if (max_depth == 0) {
893 try w.writeAll("{ ... }");
889 try w.writeAll(".{ ... }");
894890 return;
895891 }
896892 if (info.tag_type) |UnionTagType| {
897 try w.writeAll("{ .");
893 try w.writeAll(".{ .");
898894 try w.writeAll(@tagName(@as(UnionTagType, value)));
899895 try w.writeAll(" = ");
900896 inline for (info.fields) |u_field| {
......@@ -903,9 +899,22 @@ pub fn printValue(
903899 }
904900 }
905901 try w.writeAll(" }");
906 } else {
907 try w.writeByte('@');
908 try w.printIntOptions(@intFromPtr(&value), 16, .lower, options);
902 } else switch (info.layout) {
903 .auto => {
904 return w.writeAll(".{ ... }");
905 },
906 .@"extern", .@"packed" => {
907 if (info.fields.len == 0) return w.writeAll(".{}");
908 try w.writeAll(".{ ");
909 inline for (info.fields) |field| {
910 try w.writeByte('.');
911 try w.writeAll(field.name);
912 try w.writeAll(" = ");
913 try w.printValue(ANY, options, @field(value, field.name), max_depth - 1);
914 (try w.writableArray(2)).* = ", ".*;
915 }
916 w.buffer[w.end - 2 ..][0..2].* = " }".*;
917 },
909918 }
910919 },
911920 .@"struct" => |info| {
......@@ -916,10 +925,10 @@ pub fn printValue(
916925 if (info.is_tuple) {
917926 // Skip the type and field names when formatting tuples.
918927 if (max_depth == 0) {
919 try w.writeAll("{ ... }");
928 try w.writeAll(".{ ... }");
920929 return;
921930 }
922 try w.writeAll("{");
931 try w.writeAll(".{");
923932 inline for (info.fields, 0..) |f, i| {
924933 if (i == 0) {
925934 try w.writeAll(" ");
......@@ -931,12 +940,11 @@ pub fn printValue(
931940 try w.writeAll(" }");
932941 return;
933942 }
934 try w.writeAll(@typeName(T));
935943 if (max_depth == 0) {
936 try w.writeAll("{ ... }");
944 try w.writeAll(".{ ... }");
937945 return;
938946 }
939 try w.writeAll("{");
947 try w.writeAll(".{");
940948 inline for (info.fields, 0..) |f, i| {
941949 if (i == 0) {
942950 try w.writeAll(" .");
......@@ -1550,7 +1558,7 @@ fn writeMultipleOf7Leb128(w: *Writer, value: anytype) Error!void {
15501558 }
15511559}
15521560
1553test "formatValue max_depth" {
1561test "printValue max_depth" {
15541562 const Vec2 = struct {
15551563 const SelfType = @This();
15561564 x: f32,
......@@ -1595,19 +1603,19 @@ test "formatValue max_depth" {
15951603 var buf: [1000]u8 = undefined;
15961604 var w: Writer = .fixed(&buf);
15971605 try w.printValue("", .{}, inst, 0);
1598 try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ ... }", w.buffered());
1606 try testing.expectEqualStrings(".{ ... }", w.buffered());
15991607
16001608 w = .fixed(&buf);
16011609 try w.printValue("", .{}, inst, 1);
1602 try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ ... }, .tu = io.Writer.test.printValue max_depth.TU{ ... }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", w.buffered());
1610 try testing.expectEqualStrings(".{ .a = .{ ... }, .tu = .{ ... }, .e = .Two, .vec = .{ ... } }", w.buffered());
16031611
16041612 w = .fixed(&buf);
16051613 try w.printValue("", .{}, inst, 2);
1606 try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ ... }, .tu = io.Writer.test.printValue max_depth.TU{ ... }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ ... } }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", w.buffered());
1614 try testing.expectEqualStrings(".{ .a = .{ .a = .{ ... }, .tu = .{ ... }, .e = .Two, .vec = .{ ... } }, .tu = .{ .ptr = .{ ... } }, .e = .Two, .vec = .{ .x = 10.2, .y = 2.22 } }", w.buffered());
16071615
16081616 w = .fixed(&buf);
16091617 try w.printValue("", .{}, inst, 3);
1610 try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ ... }, .tu = io.Writer.test.printValue max_depth.TU{ ... }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ ... } }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ ... } } }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", w.buffered());
1618 try testing.expectEqualStrings(".{ .a = .{ .a = .{ .a = .{ ... }, .tu = .{ ... }, .e = .Two, .vec = .{ ... } }, .tu = .{ .ptr = .{ ... } }, .e = .Two, .vec = .{ .x = 10.2, .y = 2.22 } }, .tu = .{ .ptr = .{ .ptr = .{ ... } } }, .e = .Two, .vec = .{ .x = 10.2, .y = 2.22 } }", w.buffered());
16111619
16121620 const vec: @Vector(4, i32) = .{ 1, 2, 3, 4 };
16131621 w = .fixed(&buf);
lib/std/net/test.zig+9-33
......@@ -5,7 +5,6 @@ const mem = std.mem;
55const testing = std.testing;
66
77test "parse and render IP addresses at comptime" {
8 if (builtin.os.tag == .wasi) return error.SkipZigTest;
98 comptime {
109 const ipv6addr = net.Address.parseIp("::1", 0) catch unreachable;
1110 try std.testing.expectFmt("[::1]:0", "{f}", .{ipv6addr});
......@@ -21,42 +20,23 @@ test "parse and render IP addresses at comptime" {
2120}
2221
2322test "format IPv6 address with no zero runs" {
24 if (builtin.os.tag == .wasi) return error.SkipZigTest;
2523 const addr = try std.net.Address.parseIp6("2001:db8:1:2:3:4:5:6", 0);
2624 try std.testing.expectFmt("[2001:db8:1:2:3:4:5:6]:0", "{f}", .{addr});
2725}
2826
2927test "parse IPv6 addresses and check compressed form" {
30 if (builtin.os.tag == .wasi) return error.SkipZigTest;
31
32 const alloc = testing.allocator;
33
34 // 1) Parse an IPv6 address that should compress to [2001:db8::1:0:0:2]:0
35 const addr1 = try std.net.Address.parseIp6("2001:0db8:0000:0000:0001:0000:0000:0002", 0);
36
37 // 2) Parse an IPv6 address that should compress to [2001:db8::1:2]:0
38 const addr2 = try std.net.Address.parseIp6("2001:0db8:0000:0000:0000:0000:0001:0002", 0);
39
40 // 3) Parse an IPv6 address that should compress to [2001:db8:1:0:1::2]:0
41 const addr3 = try std.net.Address.parseIp6("2001:0db8:0001:0000:0001:0000:0000:0002", 0);
42
43 // Print each address in Zig's default "[ipv6]:port" form.
44 const printed1 = try std.fmt.allocPrint(alloc, "{any}", .{addr1});
45 defer testing.allocator.free(printed1);
46 const printed2 = try std.fmt.allocPrint(alloc, "{any}", .{addr2});
47 defer testing.allocator.free(printed2);
48 const printed3 = try std.fmt.allocPrint(alloc, "{any}", .{addr3});
49 defer testing.allocator.free(printed3);
50
51 // Check the exact compressed forms we expect.
52 try std.testing.expectEqualStrings("[2001:db8::1:0:0:2]:0", printed1);
53 try std.testing.expectEqualStrings("[2001:db8::1:2]:0", printed2);
54 try std.testing.expectEqualStrings("[2001:db8:1:0:1::2]:0", printed3);
28 try std.testing.expectFmt("[2001:db8::1:0:0:2]:0", "{f}", .{
29 try std.net.Address.parseIp6("2001:0db8:0000:0000:0001:0000:0000:0002", 0),
30 });
31 try std.testing.expectFmt("[2001:db8::1:2]:0", "{f}", .{
32 try std.net.Address.parseIp6("2001:0db8:0000:0000:0000:0000:0001:0002", 0),
33 });
34 try std.testing.expectFmt("[2001:db8:1:0:1::2]:0", "{f}", .{
35 try std.net.Address.parseIp6("2001:0db8:0001:0000:0001:0000:0000:0002", 0),
36 });
5537}
5638
5739test "parse IPv6 address, check raw bytes" {
58 if (builtin.os.tag == .wasi) return error.SkipZigTest;
59
6040 const expected_raw: [16]u8 = .{
6141 0x20, 0x01, 0x0d, 0xb8, // 2001:db8
6242 0x00, 0x00, 0x00, 0x00, // :0000:0000
......@@ -71,8 +51,6 @@ test "parse IPv6 address, check raw bytes" {
7151}
7252
7353test "parse and render IPv6 addresses" {
74 if (builtin.os.tag == .wasi) return error.SkipZigTest;
75
7654 var buffer: [100]u8 = undefined;
7755 const ips = [_][]const u8{
7856 "FF01:0:0:0:0:0:0:FB",
......@@ -137,8 +115,6 @@ test "invalid but parseable IPv6 scope ids" {
137115}
138116
139117test "parse and render IPv4 addresses" {
140 if (builtin.os.tag == .wasi) return error.SkipZigTest;
141
142118 var buffer: [18]u8 = undefined;
143119 for ([_][]const u8{
144120 "0.0.0.0",