Commit 78d12762a9
Changed files (1)
lib
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});
+}