diff options
| author | Benjamin Feng <benjamin.feng@glassdoor.com> | 2020-02-29 13:22:27 -0600 |
|---|---|---|
| committer | Benjamin Feng <benjamin.feng@glassdoor.com> | 2020-03-12 09:15:49 -0500 |
| commit | 78d12762a9c78f9563a3cfd29541d0a04f78ab58 (patch) | |
| tree | ead5c72d8a5e94d4cce3dba9d70e373eabf388f5 /lib/std | |
| parent | 8241b96f78fa8ee33f9a73d4d296509d49b6f351 (diff) | |
| download | zig-78d12762a9c78f9563a3cfd29541d0a04f78ab58.tar.gz zig-78d12762a9c78f9563a3cfd29541d0a04f78ab58.zip | |
Re-enable a bunch of tests
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/fmtstream.zig | 812 |
1 files changed, 405 insertions, 407 deletions
diff --git a/lib/std/fmtstream.zig b/lib/std/fmtstream.zig index 4a7d8041c0..3a2767c85a 100644 --- a/lib/std/fmtstream.zig +++ b/lib/std/fmtstream.zig @@ -430,7 +430,7 @@ pub fn formatType( }, .Many, .C => { if (ptr_info.sentinel) |sentinel| { - return formatType(mem.span(value), fmt, options, context, Errors, output, max_depth); + return formatType(mem.span(value), fmt, options, out_stream, max_depth); } if (ptr_info.child == u8) { if (fmt.len > 0 and fmt[0] == 's') { @@ -481,7 +481,7 @@ pub fn formatType( .Type => return out_stream.writeAll(@typeName(T)), .EnumLiteral => { const buffer = [_]u8{'.'} ++ @tagName(value); - return formatType(buffer, fmt, options, context, Errors, output, max_depth); + return formatType(buffer, fmt, options, out_stream, max_depth); }, else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"), } @@ -1079,11 +1079,11 @@ pub const BufPrintError = error{ BufferTooSmall, }; pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: var) BufPrintError![]u8 { - var os = std.io.SliceOutStream.init(buf); - format(&os.stream, fmt, args) catch |err| switch (err) { - error.OutOfMemory => return error.BufferTooSmall, + var fbs = std.io.fixedBufferStream(buf); + format(fbs.outStream(), fmt, args) catch |err| switch (err) { + error.NoSpaceLeft => return error.BufferTooSmall, }; - return buf[0..os.pos]; + return buf[0..fbs.pos]; } // pub const AllocPrintError = error{OutOfMemory}; @@ -1131,348 +1131,346 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options: return buf[0..formatIntBuf(buf, value, base, uppercase, options)]; } -// test "parse u64 digit too big" { -// _ = parseUnsigned(u64, "123a", 10) catch |err| { -// if (err == error.InvalidCharacter) return; -// unreachable; -// }; -// unreachable; -// } +test "parse u64 digit too big" { + _ = parseUnsigned(u64, "123a", 10) catch |err| { + if (err == error.InvalidCharacter) return; + unreachable; + }; + unreachable; +} -// test "parse unsigned comptime" { -// comptime { -// std.testing.expect((try parseUnsigned(usize, "2", 10)) == 2); -// } -// } +test "parse unsigned comptime" { + comptime { + std.testing.expect((try parseUnsigned(usize, "2", 10)) == 2); + } +} -// test "optional" { -// { -// const value: ?i32 = 1234; -// try testFmt("optional: 1234\n", "optional: {}\n", .{value}); -// } -// { -// const value: ?i32 = null; -// try testFmt("optional: null\n", "optional: {}\n", .{value}); -// } -// } +test "optional" { + { + const value: ?i32 = 1234; + try testFmt("optional: 1234\n", "optional: {}\n", .{value}); + } + { + const value: ?i32 = null; + try testFmt("optional: null\n", "optional: {}\n", .{value}); + } +} -// test "error" { -// { -// const value: anyerror!i32 = 1234; -// try testFmt("error union: 1234\n", "error union: {}\n", .{value}); -// } -// { -// const value: anyerror!i32 = error.InvalidChar; -// try testFmt("error union: error.InvalidChar\n", "error union: {}\n", .{value}); -// } -// } +test "error" { + { + const value: anyerror!i32 = 1234; + try testFmt("error union: 1234\n", "error union: {}\n", .{value}); + } + { + const value: anyerror!i32 = error.InvalidChar; + try testFmt("error union: error.InvalidChar\n", "error union: {}\n", .{value}); + } +} -// test "int.small" { -// { -// const value: u3 = 0b101; -// try testFmt("u3: 5\n", "u3: {}\n", .{value}); -// } -// } +test "int.small" { + { + const value: u3 = 0b101; + try testFmt("u3: 5\n", "u3: {}\n", .{value}); + } +} -// test "int.specifier" { -// { -// const value: u8 = 'a'; -// try testFmt("u8: a\n", "u8: {c}\n", .{value}); -// } -// { -// const value: u8 = 0b1100; -// try testFmt("u8: 0b1100\n", "u8: 0b{b}\n", .{value}); -// } -// } +test "int.specifier" { + { + const value: u8 = 'a'; + try testFmt("u8: a\n", "u8: {c}\n", .{value}); + } + { + const value: u8 = 0b1100; + try testFmt("u8: 0b1100\n", "u8: 0b{b}\n", .{value}); + } +} -// test "int.padded" { -// try testFmt("u8: ' 1'", "u8: '{:4}'", .{@as(u8, 1)}); -// try testFmt("u8: 'xxx1'", "u8: '{:x<4}'", .{@as(u8, 1)}); -// } +test "int.padded" { + try testFmt("u8: ' 1'", "u8: '{:4}'", .{@as(u8, 1)}); + try testFmt("u8: 'xxx1'", "u8: '{:x<4}'", .{@as(u8, 1)}); +} -// test "buffer" { -// { -// var buf1: [32]u8 = undefined; -// var context = BufPrintContext{ .remaining = buf1[0..] }; -// try formatType(1234, "", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth); -// var res = buf1[0 .. buf1.len - context.remaining.len]; -// std.testing.expect(mem.eql(u8, res, "1234")); - -// context = BufPrintContext{ .remaining = buf1[0..] }; -// try formatType('a', "c", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth); -// res = buf1[0 .. buf1.len - context.remaining.len]; -// std.testing.expect(mem.eql(u8, res, "a")); - -// context = BufPrintContext{ .remaining = buf1[0..] }; -// try formatType(0b1100, "b", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth); -// res = buf1[0 .. buf1.len - context.remaining.len]; -// std.testing.expect(mem.eql(u8, res, "1100")); -// } -// } +test "buffer" { + { + var buf1: [32]u8 = undefined; + var fbs = std.io.fixedBufferStream(&buf1); + try formatType(1234, "", FormatOptions{}, fbs.outStream(), default_max_depth); + var res = buf1[0..fbs.pos]; + std.testing.expect(mem.eql(u8, res, "1234")); + + try fbs.seekTo(0); + try formatType('a', "c", FormatOptions{}, fbs.outStream(), default_max_depth); + res = buf1[0..fbs.pos]; + std.testing.expect(mem.eql(u8, res, "a")); + + try fbs.seekTo(0); + try formatType(0b1100, "b", FormatOptions{}, fbs.outStream(), default_max_depth); + res = buf1[0..fbs.pos]; + std.testing.expect(mem.eql(u8, res, "1100")); + } +} -// test "array" { -// { -// const value: [3]u8 = "abc".*; -// try testFmt("array: abc\n", "array: {}\n", .{value}); -// try testFmt("array: abc\n", "array: {}\n", .{&value}); - -// var buf: [100]u8 = undefined; -// try testFmt( -// try bufPrint(buf[0..], "array: [3]u8@{x}\n", .{@ptrToInt(&value)}), -// "array: {*}\n", -// .{&value}, -// ); -// } -// } +test "array" { + { + const value: [3]u8 = "abc".*; + try testFmt("array: abc\n", "array: {}\n", .{value}); + try testFmt("array: abc\n", "array: {}\n", .{&value}); + + var buf: [100]u8 = undefined; + try testFmt( + try bufPrint(buf[0..], "array: [3]u8@{x}\n", .{@ptrToInt(&value)}), + "array: {*}\n", + .{&value}, + ); + } +} -// test "slice" { -// { -// const value: []const u8 = "abc"; -// try testFmt("slice: abc\n", "slice: {}\n", .{value}); -// } -// { -// const value = @intToPtr([*]align(1) const []const u8, 0xdeadbeef)[0..0]; -// try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", .{value}); -// } - -// try testFmt("buf: Test \n", "buf: {s:5}\n", .{"Test"}); -// try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"}); -// } +test "slice" { + { + const value: []const u8 = "abc"; + try testFmt("slice: abc\n", "slice: {}\n", .{value}); + } + { + const value = @intToPtr([*]align(1) const []const u8, 0xdeadbeef)[0..0]; + try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", .{value}); + } -// test "pointer" { -// { -// const value = @intToPtr(*align(1) i32, 0xdeadbeef); -// try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", .{value}); -// try testFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", .{value}); -// } -// { -// const value = @intToPtr(fn () void, 0xdeadbeef); -// try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value}); -// } -// { -// const value = @intToPtr(fn () void, 0xdeadbeef); -// try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value}); -// } -// } + try testFmt("buf: Test \n", "buf: {s:5}\n", .{"Test"}); + try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"}); +} -// test "cstr" { -// try testFmt( -// "cstr: Test C\n", -// "cstr: {s}\n", -// .{@ptrCast([*c]const u8, "Test C")}, -// ); -// try testFmt( -// "cstr: Test C \n", -// "cstr: {s:10}\n", -// .{@ptrCast([*c]const u8, "Test C")}, -// ); -// } +test "pointer" { + { + const value = @intToPtr(*align(1) i32, 0xdeadbeef); + try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", .{value}); + try testFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", .{value}); + } + { + const value = @intToPtr(fn () void, 0xdeadbeef); + try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value}); + } + { + const value = @intToPtr(fn () void, 0xdeadbeef); + try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value}); + } +} -// test "filesize" { -// try testFmt("file size: 63MiB\n", "file size: {Bi}\n", .{@as(usize, 63 * 1024 * 1024)}); -// try testFmt("file size: 66.06MB\n", "file size: {B:.2}\n", .{@as(usize, 63 * 1024 * 1024)}); -// } +test "cstr" { + try testFmt( + "cstr: Test C\n", + "cstr: {s}\n", + .{@ptrCast([*c]const u8, "Test C")}, + ); + try testFmt( + "cstr: Test C \n", + "cstr: {s:10}\n", + .{@ptrCast([*c]const u8, "Test C")}, + ); +} -// test "struct" { -// { -// const Struct = struct { -// field: u8, -// }; -// const value = Struct{ .field = 42 }; -// try testFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{value}); -// try testFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{&value}); -// } -// { -// const Struct = struct { -// a: u0, -// b: u1, -// }; -// const value = Struct{ .a = 0, .b = 1 }; -// try testFmt("struct: Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value}); -// } -// } +test "filesize" { + try testFmt("file size: 63MiB\n", "file size: {Bi}\n", .{@as(usize, 63 * 1024 * 1024)}); + try testFmt("file size: 66.06MB\n", "file size: {B:.2}\n", .{@as(usize, 63 * 1024 * 1024)}); +} -// test "enum" { -// const Enum = enum { -// One, -// Two, -// }; -// const value = Enum.Two; -// try testFmt("enum: Enum.Two\n", "enum: {}\n", .{value}); -// try testFmt("enum: Enum.Two\n", "enum: {}\n", .{&value}); -// } +test "struct" { + { + const Struct = struct { + field: u8, + }; + const value = Struct{ .field = 42 }; + try testFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{value}); + try testFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{&value}); + } + { + const Struct = struct { + a: u0, + b: u1, + }; + const value = Struct{ .a = 0, .b = 1 }; + try testFmt("struct: Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value}); + } +} -// test "non-exhaustive enum" { -// const Enum = enum(u16) { -// One = 0x000f, -// Two = 0xbeef, -// _, -// }; -// try testFmt("enum: Enum(15)\n", "enum: {}\n", .{Enum.One}); -// try testFmt("enum: Enum(48879)\n", "enum: {}\n", .{Enum.Two}); -// try testFmt("enum: Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)}); -// try testFmt("enum: Enum(f)\n", "enum: {x}\n", .{Enum.One}); -// try testFmt("enum: Enum(beef)\n", "enum: {x}\n", .{Enum.Two}); -// try testFmt("enum: Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)}); -// } +test "enum" { + const Enum = enum { + One, + Two, + }; + const value = Enum.Two; + try testFmt("enum: Enum.Two\n", "enum: {}\n", .{value}); + try testFmt("enum: Enum.Two\n", "enum: {}\n", .{&value}); +} -// test "float.scientific" { -// try testFmt("f32: 1.34000003e+00", "f32: {e}", .{@as(f32, 1.34)}); -// try testFmt("f32: 1.23400001e+01", "f32: {e}", .{@as(f32, 12.34)}); -// try testFmt("f64: -1.234e+11", "f64: {e}", .{@as(f64, -12.34e10)}); -// try testFmt("f64: 9.99996e-40", "f64: {e}", .{@as(f64, 9.999960e-40)}); -// } +test "non-exhaustive enum" { + const Enum = enum(u16) { + One = 0x000f, + Two = 0xbeef, + _, + }; + try testFmt("enum: Enum(15)\n", "enum: {}\n", .{Enum.One}); + try testFmt("enum: Enum(48879)\n", "enum: {}\n", .{Enum.Two}); + try testFmt("enum: Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)}); + try testFmt("enum: Enum(f)\n", "enum: {x}\n", .{Enum.One}); + try testFmt("enum: Enum(beef)\n", "enum: {x}\n", .{Enum.Two}); + try testFmt("enum: Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)}); +} -// test "float.scientific.precision" { -// try testFmt("f64: 1.40971e-42", "f64: {e:.5}", .{@as(f64, 1.409706e-42)}); -// try testFmt("f64: 1.00000e-09", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 814313563)))}); -// try testFmt("f64: 7.81250e-03", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1006632960)))}); -// // libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05. -// // In fact, libc doesn't round a lot of 5 cases up when one past the precision point. -// try testFmt("f64: 1.00001e+05", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1203982400)))}); -// } +test "float.scientific" { + try testFmt("f32: 1.34000003e+00", "f32: {e}", .{@as(f32, 1.34)}); + try testFmt("f32: 1.23400001e+01", "f32: {e}", .{@as(f32, 12.34)}); + try testFmt("f64: -1.234e+11", "f64: {e}", .{@as(f64, -12.34e10)}); + try testFmt("f64: 9.99996e-40", "f64: {e}", .{@as(f64, 9.999960e-40)}); +} -// test "float.special" { -// try testFmt("f64: nan", "f64: {}", .{math.nan_f64}); -// // negative nan is not defined by IEE 754, -// // and ARM thus normalizes it to positive nan -// if (builtin.arch != builtin.Arch.arm) { -// try testFmt("f64: -nan", "f64: {}", .{-math.nan_f64}); -// } -// try testFmt("f64: inf", "f64: {}", .{math.inf_f64}); -// try testFmt("f64: -inf", "f64: {}", .{-math.inf_f64}); -// } +test "float.scientific.precision" { + try testFmt("f64: 1.40971e-42", "f64: {e:.5}", .{@as(f64, 1.409706e-42)}); + try testFmt("f64: 1.00000e-09", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 814313563)))}); + try testFmt("f64: 7.81250e-03", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1006632960)))}); + // libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05. + // In fact, libc doesn't round a lot of 5 cases up when one past the precision point. + try testFmt("f64: 1.00001e+05", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1203982400)))}); +} -// test "float.decimal" { -// try testFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)}); -// try testFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)}); -// try testFmt("f32: 1.1", "f32: {d:.1}", .{@as(f32, 1.1234)}); -// try testFmt("f32: 1234.57", "f32: {d:.2}", .{@as(f32, 1234.567)}); -// // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64). -// // -11.12339... is rounded back up to -11.1234 -// try testFmt("f32: -11.1234", "f32: {d:.4}", .{@as(f32, -11.1234)}); -// try testFmt("f32: 91.12345", "f32: {d:.5}", .{@as(f32, 91.12345)}); -// try testFmt("f64: 91.1234567890", "f64: {d:.10}", .{@as(f64, 91.12345678901235)}); -// try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 0.0)}); -// try testFmt("f64: 6", "f64: {d:.0}", .{@as(f64, 5.700)}); -// try testFmt("f64: 10.0", "f64: {d:.1}", .{@as(f64, 9.999)}); -// try testFmt("f64: 1.000", "f64: {d:.3}", .{@as(f64, 1.0)}); -// try testFmt("f64: 0.00030000", "f64: {d:.8}", .{@as(f64, 0.0003)}); -// try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 1.40130e-45)}); -// try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 9.999960e-40)}); -// } +test "float.special" { + try testFmt("f64: nan", "f64: {}", .{math.nan_f64}); + // negative nan is not defined by IEE 754, + // and ARM thus normalizes it to positive nan + if (builtin.arch != builtin.Arch.arm) { + try testFmt("f64: -nan", "f64: {}", .{-math.nan_f64}); + } + try testFmt("f64: inf", "f64: {}", .{math.inf_f64}); + try testFmt("f64: -inf", "f64: {}", .{-math.inf_f64}); +} -// test "float.libc.sanity" { -// try testFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 916964781)))}); -// try testFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 925353389)))}); -// try testFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1036831278)))}); -// try testFmt("f64: 1.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1065353133)))}); -// try testFmt("f64: 10.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1092616192)))}); - -// // libc differences -// // -// // This is 0.015625 exactly according to gdb. We thus round down, -// // however glibc rounds up for some reason. This occurs for all -// // floats of the form x.yyyy25 on a precision point. -// try testFmt("f64: 0.01563", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1015021568)))}); -// // errol3 rounds to ... 630 but libc rounds to ...632. Grisu3 -// // also rounds to 630 so I'm inclined to believe libc is not -// // optimal here. -// try testFmt("f64: 18014400656965630.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1518338049)))}); -// } +test "float.decimal" { + try testFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)}); + try testFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)}); + try testFmt("f32: 1.1", "f32: {d:.1}", .{@as(f32, 1.1234)}); + try testFmt("f32: 1234.57", "f32: {d:.2}", .{@as(f32, 1234.567)}); + // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64). + // -11.12339... is rounded back up to -11.1234 + try testFmt("f32: -11.1234", "f32: {d:.4}", .{@as(f32, -11.1234)}); + try testFmt("f32: 91.12345", "f32: {d:.5}", .{@as(f32, 91.12345)}); + try testFmt("f64: 91.1234567890", "f64: {d:.10}", .{@as(f64, 91.12345678901235)}); + try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 0.0)}); + try testFmt("f64: 6", "f64: {d:.0}", .{@as(f64, 5.700)}); + try testFmt("f64: 10.0", "f64: {d:.1}", .{@as(f64, 9.999)}); + try testFmt("f64: 1.000", "f64: {d:.3}", .{@as(f64, 1.0)}); + try testFmt("f64: 0.00030000", "f64: {d:.8}", .{@as(f64, 0.0003)}); + try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 1.40130e-45)}); + try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 9.999960e-40)}); +} -// test "custom" { -// const Vec2 = struct { -// const SelfType = @This(); -// x: f32, -// y: f32, +test "float.libc.sanity" { + try testFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 916964781)))}); + try testFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 925353389)))}); + try testFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1036831278)))}); + try testFmt("f64: 1.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1065353133)))}); + try testFmt("f64: 10.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1092616192)))}); + + // libc differences + // + // This is 0.015625 exactly according to gdb. We thus round down, + // however glibc rounds up for some reason. This occurs for all + // floats of the form x.yyyy25 on a precision point. + try testFmt("f64: 0.01563", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1015021568)))}); + // errol3 rounds to ... 630 but libc rounds to ...632. Grisu3 + // also rounds to 630 so I'm inclined to believe libc is not + // optimal here. + try testFmt("f64: 18014400656965630.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1518338049)))}); +} -// pub fn format( -// self: SelfType, -// comptime fmt: []const u8, -// options: FormatOptions, -// context: var, -// comptime Errors: type, -// comptime output: fn (@TypeOf(context), []const u8) !void, -// ) !void { -// if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "p")) { -// return std.fmtstream.format(out_stream, "({d:.3},{d:.3})", .{ self.x, self.y }); -// } else if (comptime std.mem.eql(u8, fmt, "d")) { -// return std.fmtstream.format(out_stream, "{d:.3}x{d:.3}", .{ self.x, self.y }); -// } else { -// @compileError("Unknown format character: '" ++ fmt ++ "'"); -// } -// } -// }; +test "custom" { + const Vec2 = struct { + const SelfType = @This(); + x: f32, + y: f32, + + pub fn format( + self: SelfType, + comptime fmt: []const u8, + options: FormatOptions, + out_stream: var, + ) !void { + if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "p")) { + return std.fmtstream.format(out_stream, "({d:.3},{d:.3})", .{ self.x, self.y }); + } else if (comptime std.mem.eql(u8, fmt, "d")) { + return std.fmtstream.format(out_stream, "{d:.3}x{d:.3}", .{ self.x, self.y }); + } else { + @compileError("Unknown format character: '" ++ fmt ++ "'"); + } + } + }; -// var buf1: [32]u8 = undefined; -// var value = Vec2{ -// .x = 10.2, -// .y = 2.22, -// }; -// try testFmt("point: (10.200,2.220)\n", "point: {}\n", .{&value}); -// try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{&value}); + var buf1: [32]u8 = undefined; + var value = Vec2{ + .x = 10.2, + .y = 2.22, + }; + try testFmt("point: (10.200,2.220)\n", "point: {}\n", .{&value}); + try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{&value}); -// // same thing but not passing a pointer -// try testFmt("point: (10.200,2.220)\n", "point: {}\n", .{value}); -// try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{value}); -// } + // same thing but not passing a pointer + try testFmt("point: (10.200,2.220)\n", "point: {}\n", .{value}); + try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{value}); +} -// test "struct" { -// const S = struct { -// a: u32, -// b: anyerror, -// }; +test "struct" { + const S = struct { + a: u32, + b: anyerror, + }; -// const inst = S{ -// .a = 456, -// .b = error.Unused, -// }; + const inst = S{ + .a = 456, + .b = error.Unused, + }; -// try testFmt("S{ .a = 456, .b = error.Unused }", "{}", .{inst}); -// } + try testFmt("S{ .a = 456, .b = error.Unused }", "{}", .{inst}); +} -// test "union" { -// const TU = union(enum) { -// float: f32, -// int: u32, -// }; +test "union" { + const TU = union(enum) { + float: f32, + int: u32, + }; -// const UU = union { -// float: f32, -// int: u32, -// }; + const UU = union { + float: f32, + int: u32, + }; -// const EU = extern union { -// float: f32, -// int: u32, -// }; + const EU = extern union { + float: f32, + int: u32, + }; -// const tu_inst = TU{ .int = 123 }; -// const uu_inst = UU{ .int = 456 }; -// const eu_inst = EU{ .float = 321.123 }; + const tu_inst = TU{ .int = 123 }; + const uu_inst = UU{ .int = 456 }; + const eu_inst = EU{ .float = 321.123 }; -// try testFmt("TU{ .int = 123 }", "{}", .{tu_inst}); + try testFmt("TU{ .int = 123 }", "{}", .{tu_inst}); -// var buf: [100]u8 = undefined; -// const uu_result = try bufPrint(buf[0..], "{}", .{uu_inst}); -// std.testing.expect(mem.eql(u8, uu_result[0..3], "UU@")); + var buf: [100]u8 = undefined; + const uu_result = try bufPrint(buf[0..], "{}", .{uu_inst}); + std.testing.expect(mem.eql(u8, uu_result[0..3], "UU@")); -// const eu_result = try bufPrint(buf[0..], "{}", .{eu_inst}); -// std.testing.expect(mem.eql(u8, uu_result[0..3], "EU@")); -// } + const eu_result = try bufPrint(buf[0..], "{}", .{eu_inst}); + std.testing.expect(mem.eql(u8, uu_result[0..3], "EU@")); +} -// test "enum" { -// const E = enum { -// One, -// Two, -// Three, -// }; +test "enum" { + const E = enum { + One, + Two, + Three, + }; -// const inst = E.Two; + const inst = E.Two; -// try testFmt("E.Two", "{}", .{inst}); -// } + try testFmt("E.Two", "{}", .{inst}); +} // test "struct.self-referential" { // const S = struct { @@ -1488,20 +1486,20 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options: // try testFmt("S{ .a = S{ .a = S{ .a = S{ ... } } } }", "{}", .{inst}); // } -// test "struct.zero-size" { -// const A = struct { -// fn foo() void {} -// }; -// const B = struct { -// a: A, -// c: i32, -// }; +test "struct.zero-size" { + const A = struct { + fn foo() void {} + }; + const B = struct { + a: A, + c: i32, + }; -// const a = A{}; -// const b = B{ .a = a, .c = 0 }; + const a = A{}; + const b = B{ .a = a, .c = 0 }; -// try testFmt("B{ .a = A{ }, .c = 0 }", "{}", .{b}); -// } + try testFmt("B{ .a = A{ }, .c = 0 }", "{}", .{b}); +} test "bytes.hex" { const some_bytes = "\xCA\xFE\xBA\xBE"; @@ -1527,66 +1525,66 @@ fn testFmt(expected: []const u8, comptime template: []const u8, args: var) !void return error.TestFailed; } -// pub fn trim(buf: []const u8) []const u8 { -// var start: usize = 0; -// while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) {} +pub fn trim(buf: []const u8) []const u8 { + var start: usize = 0; + while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) {} -// var end: usize = buf.len; -// while (true) { -// if (end > start) { -// const new_end = end - 1; -// if (isWhiteSpace(buf[new_end])) { -// end = new_end; -// continue; -// } -// } -// break; -// } -// return buf[start..end]; -// } + var end: usize = buf.len; + while (true) { + if (end > start) { + const new_end = end - 1; + if (isWhiteSpace(buf[new_end])) { + end = new_end; + continue; + } + } + break; + } + return buf[start..end]; +} -// test "trim" { -// std.testing.expect(mem.eql(u8, "abc", trim("\n abc \t"))); -// std.testing.expect(mem.eql(u8, "", trim(" "))); -// std.testing.expect(mem.eql(u8, "", trim(""))); -// std.testing.expect(mem.eql(u8, "abc", trim(" abc"))); -// std.testing.expect(mem.eql(u8, "abc", trim("abc "))); -// } +test "trim" { + std.testing.expect(mem.eql(u8, "abc", trim("\n abc \t"))); + std.testing.expect(mem.eql(u8, "", trim(" "))); + std.testing.expect(mem.eql(u8, "", trim(""))); + std.testing.expect(mem.eql(u8, "abc", trim(" abc"))); + std.testing.expect(mem.eql(u8, "abc", trim("abc "))); +} -// pub fn isWhiteSpace(byte: u8) bool { -// return switch (byte) { -// ' ', '\t', '\n', '\r' => true, -// else => false, -// }; -// } +pub fn isWhiteSpace(byte: u8) bool { + return switch (byte) { + ' ', '\t', '\n', '\r' => true, + else => false, + }; +} -// pub fn hexToBytes(out: []u8, input: []const u8) !void { -// if (out.len * 2 < input.len) -// return error.InvalidLength; +pub fn hexToBytes(out: []u8, input: []const u8) !void { + if (out.len * 2 < input.len) + return error.InvalidLength; -// var in_i: usize = 0; -// while (in_i != input.len) : (in_i += 2) { -// const hi = try charToDigit(input[in_i], 16); -// const lo = try charToDigit(input[in_i + 1], 16); -// out[in_i / 2] = (hi << 4) | lo; -// } -// } + var in_i: usize = 0; + while (in_i != input.len) : (in_i += 2) { + const hi = try charToDigit(input[in_i], 16); + const lo = try charToDigit(input[in_i + 1], 16); + out[in_i / 2] = (hi << 4) | lo; + } +} -// test "hexToBytes" { -// const test_hex_str = "909A312BB12ED1F819B3521AC4C1E896F2160507FFC1C8381E3B07BB16BD1706"; -// var pb: [32]u8 = undefined; -// try hexToBytes(pb[0..], test_hex_str); -// try testFmt(test_hex_str, "{X}", .{pb}); -// } +test "hexToBytes" { + const test_hex_str = "909A312BB12ED1F819B3521AC4C1E896F2160507FFC1C8381E3B07BB16BD1706"; + var pb: [32]u8 = undefined; + try hexToBytes(pb[0..], test_hex_str); + try testFmt(test_hex_str, "{X}", .{pb}); +} -// test "formatIntValue with comptime_int" { -// const value: comptime_int = 123456789123456789; +test "formatIntValue with comptime_int" { + const value: comptime_int = 123456789123456789; -// var buf = std.ArrayList(u8).init(std.testing.allocator); -// defer buf.deinit(); -// try formatIntValue(value, "", FormatOptions{}, &buf, @TypeOf(std.ArrayList(u8).appendSlice).ReturnType.ErrorSet, std.ArrayList(u8).appendSlice); -// std.testing.expect(mem.eql(u8, buf.toSliceConst(), "123456789123456789")); -// } + var buf: [20]u8 = undefined; + var fbs = std.io.fixedBufferStream(&buf); + try formatIntValue(value, "", FormatOptions{}, fbs.outStream()); + std.testing.expect(mem.eql(u8, buf[0..fbs.pos], "123456789123456789")); +} // test "formatType max_depth" { // const Vec2 = struct { @@ -1658,39 +1656,39 @@ fn testFmt(expected: []const u8, comptime template: []const u8, args: var) !void // std.testing.expect(mem.eql(u8, buf3.toSlice(), "S{ .a = S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ .ptr = TU{ ... } } }, .e = E.Two, .vec = (10.200,2.220) }")); // } -// test "positional" { -// try testFmt("2 1 0", "{2} {1} {0}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) }); -// try testFmt("2 1 0", "{2} {1} {}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) }); -// try testFmt("0 0", "{0} {0}", .{@as(usize, 0)}); -// try testFmt("0 1", "{} {1}", .{ @as(usize, 0), @as(usize, 1) }); -// try testFmt("1 0 0 1", "{1} {} {0} {}", .{ @as(usize, 0), @as(usize, 1) }); -// } +test "positional" { + try testFmt("2 1 0", "{2} {1} {0}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) }); + try testFmt("2 1 0", "{2} {1} {}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) }); + try testFmt("0 0", "{0} {0}", .{@as(usize, 0)}); + try testFmt("0 1", "{} {1}", .{ @as(usize, 0), @as(usize, 1) }); + try testFmt("1 0 0 1", "{1} {} {0} {}", .{ @as(usize, 0), @as(usize, 1) }); +} -// test "positional with specifier" { -// try testFmt("10.0", "{0d:.1}", .{@as(f64, 9.999)}); -// } +test "positional with specifier" { + try testFmt("10.0", "{0d:.1}", .{@as(f64, 9.999)}); +} -// test "positional/alignment/width/precision" { -// try testFmt("10.0", "{0d: >3.1}", .{@as(f64, 9.999)}); -// } +test "positional/alignment/width/precision" { + try testFmt("10.0", "{0d: >3.1}", .{@as(f64, 9.999)}); +} -// test "vector" { -// // https://github.com/ziglang/zig/issues/3317 -// if (builtin.arch == .mipsel) return error.SkipZigTest; - -// const vbool: @Vector(4, bool) = [_]bool{ true, false, true, false }; -// const vi64: @Vector(4, i64) = [_]i64{ -2, -1, 0, 1 }; -// const vu64: @Vector(4, u64) = [_]u64{ 1000, 2000, 3000, 4000 }; - -// try testFmt("{ true, false, true, false }", "{}", .{vbool}); -// try testFmt("{ -2, -1, 0, 1 }", "{}", .{vi64}); -// try testFmt("{ - 2, - 1, + 0, + 1 }", "{d:5}", .{vi64}); -// try testFmt("{ 1000, 2000, 3000, 4000 }", "{}", .{vu64}); -// try testFmt("{ 3e8, 7d0, bb8, fa0 }", "{x}", .{vu64}); -// try testFmt("{ 1kB, 2kB, 3kB, 4kB }", "{B}", .{vu64}); -// try testFmt("{ 1000B, 1.953125KiB, 2.9296875KiB, 3.90625KiB }", "{Bi}", .{vu64}); -// } +test "vector" { + // https://github.com/ziglang/zig/issues/3317 + if (builtin.arch == .mipsel) return error.SkipZigTest; + + const vbool: @Vector(4, bool) = [_]bool{ true, false, true, false }; + const vi64: @Vector(4, i64) = [_]i64{ -2, -1, 0, 1 }; + const vu64: @Vector(4, u64) = [_]u64{ 1000, 2000, 3000, 4000 }; + + try testFmt("{ true, false, true, false }", "{}", .{vbool}); + try testFmt("{ -2, -1, 0, 1 }", "{}", .{vi64}); + try testFmt("{ - 2, - 1, + 0, + 1 }", "{d:5}", .{vi64}); + try testFmt("{ 1000, 2000, 3000, 4000 }", "{}", .{vu64}); + try testFmt("{ 3e8, 7d0, bb8, fa0 }", "{x}", .{vu64}); + try testFmt("{ 1kB, 2kB, 3kB, 4kB }", "{B}", .{vu64}); + try testFmt("{ 1000B, 1.953125KiB, 2.9296875KiB, 3.90625KiB }", "{Bi}", .{vu64}); +} -// test "enum-literal" { -// try testFmt(".hello_world", "{}", .{.hello_world}); -// } +test "enum-literal" { + try testFmt(".hello_world", "{}", .{.hello_world}); +} |
