authorgravatar for benjamin.feng@glassdoor.comBenjamin Feng <benjamin.feng@glassdoor.com> 2020-02-29 13:22:27-06:00
committergravatar for benjamin.feng@glassdoor.comBenjamin Feng <benjamin.feng@glassdoor.com> 2020-03-12 09:15:49-05:00
log78d12762a9c78f9563a3cfd29541d0a04f78ab58
treeead5c72d8a5e94d4cce3dba9d70e373eabf388f5
parent8241b96f78fa8ee33f9a73d4d296509d49b6f351

Re-enable a bunch of tests


1 files changed, 405 insertions(+), 407 deletions(-)

lib/std/fmtstream.zig+405-407
...@@ -430,7 +430,7 @@ pub fn formatType(...@@ -430,7 +430,7 @@ pub fn formatType(
430 },430 },
431 .Many, .C => {431 .Many, .C => {
432 if (ptr_info.sentinel) |sentinel| {432 if (ptr_info.sentinel) |sentinel| {
433 return formatType(mem.span(value), fmt, options, context, Errors, output, max_depth);433 return formatType(mem.span(value), fmt, options, out_stream, max_depth);
434 }434 }
435 if (ptr_info.child == u8) {435 if (ptr_info.child == u8) {
436 if (fmt.len > 0 and fmt[0] == 's') {436 if (fmt.len > 0 and fmt[0] == 's') {
...@@ -481,7 +481,7 @@ pub fn formatType(...@@ -481,7 +481,7 @@ pub fn formatType(
481 .Type => return out_stream.writeAll(@typeName(T)),481 .Type => return out_stream.writeAll(@typeName(T)),
482 .EnumLiteral => {482 .EnumLiteral => {
483 const buffer = [_]u8{'.'} ++ @tagName(value);483 const buffer = [_]u8{'.'} ++ @tagName(value);
484 return formatType(buffer, fmt, options, context, Errors, output, max_depth);484 return formatType(buffer, fmt, options, out_stream, max_depth);
485 },485 },
486 else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),486 else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),
487 }487 }
...@@ -1079,11 +1079,11 @@ pub const BufPrintError = error{...@@ -1079,11 +1079,11 @@ pub const BufPrintError = error{
1079 BufferTooSmall,1079 BufferTooSmall,
1080};1080};
1081pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: var) BufPrintError![]u8 {1081pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: var) BufPrintError![]u8 {
1082 var os = std.io.SliceOutStream.init(buf);1082 var fbs = std.io.fixedBufferStream(buf);
1083 format(&os.stream, fmt, args) catch |err| switch (err) {1083 format(fbs.outStream(), fmt, args) catch |err| switch (err) {
1084 error.OutOfMemory => return error.BufferTooSmall,1084 error.NoSpaceLeft => return error.BufferTooSmall,
1085 };1085 };
1086 return buf[0..os.pos];1086 return buf[0..fbs.pos];
1087}1087}
10881088
1089// pub const AllocPrintError = error{OutOfMemory};1089// pub const AllocPrintError = error{OutOfMemory};
...@@ -1131,348 +1131,346 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options:...@@ -1131,348 +1131,346 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options:
1131 return buf[0..formatIntBuf(buf, value, base, uppercase, options)];1131 return buf[0..formatIntBuf(buf, value, base, uppercase, options)];
1132}1132}
11331133
1134// test "parse u64 digit too big" {1134test "parse u64 digit too big" {
1135// _ = parseUnsigned(u64, "123a", 10) catch |err| {1135 _ = parseUnsigned(u64, "123a", 10) catch |err| {
1136// if (err == error.InvalidCharacter) return;1136 if (err == error.InvalidCharacter) return;
1137// unreachable;1137 unreachable;
1138// };1138 };
1139// unreachable;1139 unreachable;
1140// }1140}
11411141
1142// test "parse unsigned comptime" {1142test "parse unsigned comptime" {
1143// comptime {1143 comptime {
1144// std.testing.expect((try parseUnsigned(usize, "2", 10)) == 2);1144 std.testing.expect((try parseUnsigned(usize, "2", 10)) == 2);
1145// }1145 }
1146// }1146}
11471147
1148// test "optional" {1148test "optional" {
1149// {1149 {
1150// const value: ?i32 = 1234;1150 const value: ?i32 = 1234;
1151// try testFmt("optional: 1234\n", "optional: {}\n", .{value});1151 try testFmt("optional: 1234\n", "optional: {}\n", .{value});
1152// }1152 }
1153// {1153 {
1154// const value: ?i32 = null;1154 const value: ?i32 = null;
1155// try testFmt("optional: null\n", "optional: {}\n", .{value});1155 try testFmt("optional: null\n", "optional: {}\n", .{value});
1156// }1156 }
1157// }1157}
11581158
1159// test "error" {1159test "error" {
1160// {1160 {
1161// const value: anyerror!i32 = 1234;1161 const value: anyerror!i32 = 1234;
1162// try testFmt("error union: 1234\n", "error union: {}\n", .{value});1162 try testFmt("error union: 1234\n", "error union: {}\n", .{value});
1163// }1163 }
1164// {1164 {
1165// const value: anyerror!i32 = error.InvalidChar;1165 const value: anyerror!i32 = error.InvalidChar;
1166// try testFmt("error union: error.InvalidChar\n", "error union: {}\n", .{value});1166 try testFmt("error union: error.InvalidChar\n", "error union: {}\n", .{value});
1167// }1167 }
1168// }1168}
11691169
1170// test "int.small" {1170test "int.small" {
1171// {1171 {
1172// const value: u3 = 0b101;1172 const value: u3 = 0b101;
1173// try testFmt("u3: 5\n", "u3: {}\n", .{value});1173 try testFmt("u3: 5\n", "u3: {}\n", .{value});
1174// }1174 }
1175// }1175}
11761176
1177// test "int.specifier" {1177test "int.specifier" {
1178// {1178 {
1179// const value: u8 = 'a';1179 const value: u8 = 'a';
1180// try testFmt("u8: a\n", "u8: {c}\n", .{value});1180 try testFmt("u8: a\n", "u8: {c}\n", .{value});
1181// }1181 }
1182// {1182 {
1183// const value: u8 = 0b1100;1183 const value: u8 = 0b1100;
1184// try testFmt("u8: 0b1100\n", "u8: 0b{b}\n", .{value});1184 try testFmt("u8: 0b1100\n", "u8: 0b{b}\n", .{value});
1185// }1185 }
1186// }1186}
11871187
1188// test "int.padded" {1188test "int.padded" {
1189// try testFmt("u8: ' 1'", "u8: '{:4}'", .{@as(u8, 1)});1189 try testFmt("u8: ' 1'", "u8: '{:4}'", .{@as(u8, 1)});
1190// try testFmt("u8: 'xxx1'", "u8: '{:x<4}'", .{@as(u8, 1)});1190 try testFmt("u8: 'xxx1'", "u8: '{:x<4}'", .{@as(u8, 1)});
1191// }1191}
11921192
1193// test "buffer" {1193test "buffer" {
1194// {1194 {
1195// var buf1: [32]u8 = undefined;1195 var buf1: [32]u8 = undefined;
1196// var context = BufPrintContext{ .remaining = buf1[0..] };1196 var fbs = std.io.fixedBufferStream(&buf1);
1197// try formatType(1234, "", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);1197 try formatType(1234, "", FormatOptions{}, fbs.outStream(), default_max_depth);
1198// var res = buf1[0 .. buf1.len - context.remaining.len];1198 var res = buf1[0..fbs.pos];
1199// std.testing.expect(mem.eql(u8, res, "1234"));1199 std.testing.expect(mem.eql(u8, res, "1234"));
12001200
1201// context = BufPrintContext{ .remaining = buf1[0..] };1201 try fbs.seekTo(0);
1202// try formatType('a', "c", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);1202 try formatType('a', "c", FormatOptions{}, fbs.outStream(), default_max_depth);
1203// res = buf1[0 .. buf1.len - context.remaining.len];1203 res = buf1[0..fbs.pos];
1204// std.testing.expect(mem.eql(u8, res, "a"));1204 std.testing.expect(mem.eql(u8, res, "a"));
12051205
1206// context = BufPrintContext{ .remaining = buf1[0..] };1206 try fbs.seekTo(0);
1207// try formatType(0b1100, "b", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);1207 try formatType(0b1100, "b", FormatOptions{}, fbs.outStream(), default_max_depth);
1208// res = buf1[0 .. buf1.len - context.remaining.len];1208 res = buf1[0..fbs.pos];
1209// std.testing.expect(mem.eql(u8, res, "1100"));1209 std.testing.expect(mem.eql(u8, res, "1100"));
1210// }1210 }
1211// }1211}
12121212
1213// test "array" {1213test "array" {
1214// {1214 {
1215// const value: [3]u8 = "abc".*;1215 const value: [3]u8 = "abc".*;
1216// try testFmt("array: abc\n", "array: {}\n", .{value});1216 try testFmt("array: abc\n", "array: {}\n", .{value});
1217// try testFmt("array: abc\n", "array: {}\n", .{&value});1217 try testFmt("array: abc\n", "array: {}\n", .{&value});
12181218
1219// var buf: [100]u8 = undefined;1219 var buf: [100]u8 = undefined;
1220// try testFmt(1220 try testFmt(
1221// try bufPrint(buf[0..], "array: [3]u8@{x}\n", .{@ptrToInt(&value)}),1221 try bufPrint(buf[0..], "array: [3]u8@{x}\n", .{@ptrToInt(&value)}),
1222// "array: {*}\n",1222 "array: {*}\n",
1223// .{&value},1223 .{&value},
1224// );1224 );
1225// }1225 }
1226// }1226}
12271227
1228// test "slice" {1228test "slice" {
1229// {1229 {
1230// const value: []const u8 = "abc";1230 const value: []const u8 = "abc";
1231// try testFmt("slice: abc\n", "slice: {}\n", .{value});1231 try testFmt("slice: abc\n", "slice: {}\n", .{value});
1232// }1232 }
1233// {1233 {
1234// const value = @intToPtr([*]align(1) const []const u8, 0xdeadbeef)[0..0];1234 const value = @intToPtr([*]align(1) const []const u8, 0xdeadbeef)[0..0];
1235// try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", .{value});1235 try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", .{value});
1236// }1236 }
1237
1238// try testFmt("buf: Test \n", "buf: {s:5}\n", .{"Test"});
1239// try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"});
1240// }
12411237
1242// test "pointer" {1238 try testFmt("buf: Test \n", "buf: {s:5}\n", .{"Test"});
1243// {1239 try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"});
1244// const value = @intToPtr(*align(1) i32, 0xdeadbeef);1240}
1245// try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", .{value});
1246// try testFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", .{value});
1247// }
1248// {
1249// const value = @intToPtr(fn () void, 0xdeadbeef);
1250// try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});
1251// }
1252// {
1253// const value = @intToPtr(fn () void, 0xdeadbeef);
1254// try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});
1255// }
1256// }
12571241
1258// test "cstr" {1242test "pointer" {
1259// try testFmt(1243 {
1260// "cstr: Test C\n",1244 const value = @intToPtr(*align(1) i32, 0xdeadbeef);
1261// "cstr: {s}\n",1245 try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", .{value});
1262// .{@ptrCast([*c]const u8, "Test C")},1246 try testFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", .{value});
1263// );1247 }
1264// try testFmt(1248 {
1265// "cstr: Test C \n",1249 const value = @intToPtr(fn () void, 0xdeadbeef);
1266// "cstr: {s:10}\n",1250 try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});
1267// .{@ptrCast([*c]const u8, "Test C")},1251 }
1268// );1252 {
1269// }1253 const value = @intToPtr(fn () void, 0xdeadbeef);
1254 try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});
1255 }
1256}
12701257
1271// test "filesize" {1258test "cstr" {
1272// try testFmt("file size: 63MiB\n", "file size: {Bi}\n", .{@as(usize, 63 * 1024 * 1024)});1259 try testFmt(
1273// try testFmt("file size: 66.06MB\n", "file size: {B:.2}\n", .{@as(usize, 63 * 1024 * 1024)});1260 "cstr: Test C\n",
1274// }1261 "cstr: {s}\n",
1262 .{@ptrCast([*c]const u8, "Test C")},
1263 );
1264 try testFmt(
1265 "cstr: Test C \n",
1266 "cstr: {s:10}\n",
1267 .{@ptrCast([*c]const u8, "Test C")},
1268 );
1269}
12751270
1276// test "struct" {1271test "filesize" {
1277// {1272 try testFmt("file size: 63MiB\n", "file size: {Bi}\n", .{@as(usize, 63 * 1024 * 1024)});
1278// const Struct = struct {1273 try testFmt("file size: 66.06MB\n", "file size: {B:.2}\n", .{@as(usize, 63 * 1024 * 1024)});
1279// field: u8,1274}
1280// };
1281// const value = Struct{ .field = 42 };
1282// try testFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{value});
1283// try testFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{&value});
1284// }
1285// {
1286// const Struct = struct {
1287// a: u0,
1288// b: u1,
1289// };
1290// const value = Struct{ .a = 0, .b = 1 };
1291// try testFmt("struct: Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
1292// }
1293// }
12941275
1295// test "enum" {1276test "struct" {
1296// const Enum = enum {1277 {
1297// One,1278 const Struct = struct {
1298// Two,1279 field: u8,
1299// };1280 };
1300// const value = Enum.Two;1281 const value = Struct{ .field = 42 };
1301// try testFmt("enum: Enum.Two\n", "enum: {}\n", .{value});1282 try testFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{value});
1302// try testFmt("enum: Enum.Two\n", "enum: {}\n", .{&value});1283 try testFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{&value});
1303// }1284 }
1285 {
1286 const Struct = struct {
1287 a: u0,
1288 b: u1,
1289 };
1290 const value = Struct{ .a = 0, .b = 1 };
1291 try testFmt("struct: Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
1292 }
1293}
13041294
1305// test "non-exhaustive enum" {1295test "enum" {
1306// const Enum = enum(u16) {1296 const Enum = enum {
1307// One = 0x000f,1297 One,
1308// Two = 0xbeef,1298 Two,
1309// _,1299 };
1310// };1300 const value = Enum.Two;
1311// try testFmt("enum: Enum(15)\n", "enum: {}\n", .{Enum.One});1301 try testFmt("enum: Enum.Two\n", "enum: {}\n", .{value});
1312// try testFmt("enum: Enum(48879)\n", "enum: {}\n", .{Enum.Two});1302 try testFmt("enum: Enum.Two\n", "enum: {}\n", .{&value});
1313// try testFmt("enum: Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)});1303}
1314// try testFmt("enum: Enum(f)\n", "enum: {x}\n", .{Enum.One});
1315// try testFmt("enum: Enum(beef)\n", "enum: {x}\n", .{Enum.Two});
1316// try testFmt("enum: Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)});
1317// }
13181304
1319// test "float.scientific" {1305test "non-exhaustive enum" {
1320// try testFmt("f32: 1.34000003e+00", "f32: {e}", .{@as(f32, 1.34)});1306 const Enum = enum(u16) {
1321// try testFmt("f32: 1.23400001e+01", "f32: {e}", .{@as(f32, 12.34)});1307 One = 0x000f,
1322// try testFmt("f64: -1.234e+11", "f64: {e}", .{@as(f64, -12.34e10)});1308 Two = 0xbeef,
1323// try testFmt("f64: 9.99996e-40", "f64: {e}", .{@as(f64, 9.999960e-40)});1309 _,
1324// }1310 };
1311 try testFmt("enum: Enum(15)\n", "enum: {}\n", .{Enum.One});
1312 try testFmt("enum: Enum(48879)\n", "enum: {}\n", .{Enum.Two});
1313 try testFmt("enum: Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)});
1314 try testFmt("enum: Enum(f)\n", "enum: {x}\n", .{Enum.One});
1315 try testFmt("enum: Enum(beef)\n", "enum: {x}\n", .{Enum.Two});
1316 try testFmt("enum: Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)});
1317}
13251318
1326// test "float.scientific.precision" {1319test "float.scientific" {
1327// try testFmt("f64: 1.40971e-42", "f64: {e:.5}", .{@as(f64, 1.409706e-42)});1320 try testFmt("f32: 1.34000003e+00", "f32: {e}", .{@as(f32, 1.34)});
1328// try testFmt("f64: 1.00000e-09", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 814313563)))});1321 try testFmt("f32: 1.23400001e+01", "f32: {e}", .{@as(f32, 12.34)});
1329// try testFmt("f64: 7.81250e-03", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1006632960)))});1322 try testFmt("f64: -1.234e+11", "f64: {e}", .{@as(f64, -12.34e10)});
1330// // libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05.1323 try testFmt("f64: 9.99996e-40", "f64: {e}", .{@as(f64, 9.999960e-40)});
1331// // In fact, libc doesn't round a lot of 5 cases up when one past the precision point.1324}
1332// try testFmt("f64: 1.00001e+05", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1203982400)))});
1333// }
13341325
1335// test "float.special" {1326test "float.scientific.precision" {
1336// try testFmt("f64: nan", "f64: {}", .{math.nan_f64});1327 try testFmt("f64: 1.40971e-42", "f64: {e:.5}", .{@as(f64, 1.409706e-42)});
1337// // negative nan is not defined by IEE 754,1328 try testFmt("f64: 1.00000e-09", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 814313563)))});
1338// // and ARM thus normalizes it to positive nan1329 try testFmt("f64: 7.81250e-03", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1006632960)))});
1339// if (builtin.arch != builtin.Arch.arm) {1330 // libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05.
1340// try testFmt("f64: -nan", "f64: {}", .{-math.nan_f64});1331 // In fact, libc doesn't round a lot of 5 cases up when one past the precision point.
1341// }1332 try testFmt("f64: 1.00001e+05", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1203982400)))});
1342// try testFmt("f64: inf", "f64: {}", .{math.inf_f64});1333}
1343// try testFmt("f64: -inf", "f64: {}", .{-math.inf_f64});
1344// }
13451334
1346// test "float.decimal" {1335test "float.special" {
1347// try testFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)});1336 try testFmt("f64: nan", "f64: {}", .{math.nan_f64});
1348// try testFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)});1337 // negative nan is not defined by IEE 754,
1349// try testFmt("f32: 1.1", "f32: {d:.1}", .{@as(f32, 1.1234)});1338 // and ARM thus normalizes it to positive nan
1350// try testFmt("f32: 1234.57", "f32: {d:.2}", .{@as(f32, 1234.567)});1339 if (builtin.arch != builtin.Arch.arm) {
1351// // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).1340 try testFmt("f64: -nan", "f64: {}", .{-math.nan_f64});
1352// // -11.12339... is rounded back up to -11.12341341 }
1353// try testFmt("f32: -11.1234", "f32: {d:.4}", .{@as(f32, -11.1234)});1342 try testFmt("f64: inf", "f64: {}", .{math.inf_f64});
1354// try testFmt("f32: 91.12345", "f32: {d:.5}", .{@as(f32, 91.12345)});1343 try testFmt("f64: -inf", "f64: {}", .{-math.inf_f64});
1355// try testFmt("f64: 91.1234567890", "f64: {d:.10}", .{@as(f64, 91.12345678901235)});1344}
1356// try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 0.0)});
1357// try testFmt("f64: 6", "f64: {d:.0}", .{@as(f64, 5.700)});
1358// try testFmt("f64: 10.0", "f64: {d:.1}", .{@as(f64, 9.999)});
1359// try testFmt("f64: 1.000", "f64: {d:.3}", .{@as(f64, 1.0)});
1360// try testFmt("f64: 0.00030000", "f64: {d:.8}", .{@as(f64, 0.0003)});
1361// try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 1.40130e-45)});
1362// try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 9.999960e-40)});
1363// }
13641345
1365// test "float.libc.sanity" {1346test "float.decimal" {
1366// try testFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 916964781)))});1347 try testFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)});
1367// try testFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 925353389)))});1348 try testFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)});
1368// try testFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1036831278)))});1349 try testFmt("f32: 1.1", "f32: {d:.1}", .{@as(f32, 1.1234)});
1369// try testFmt("f64: 1.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1065353133)))});1350 try testFmt("f32: 1234.57", "f32: {d:.2}", .{@as(f32, 1234.567)});
1370// try testFmt("f64: 10.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1092616192)))});1351 // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
13711352 // -11.12339... is rounded back up to -11.1234
1372// // libc differences1353 try testFmt("f32: -11.1234", "f32: {d:.4}", .{@as(f32, -11.1234)});
1373// //1354 try testFmt("f32: 91.12345", "f32: {d:.5}", .{@as(f32, 91.12345)});
1374// // This is 0.015625 exactly according to gdb. We thus round down,1355 try testFmt("f64: 91.1234567890", "f64: {d:.10}", .{@as(f64, 91.12345678901235)});
1375// // however glibc rounds up for some reason. This occurs for all1356 try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 0.0)});
1376// // floats of the form x.yyyy25 on a precision point.1357 try testFmt("f64: 6", "f64: {d:.0}", .{@as(f64, 5.700)});
1377// try testFmt("f64: 0.01563", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1015021568)))});1358 try testFmt("f64: 10.0", "f64: {d:.1}", .{@as(f64, 9.999)});
1378// // errol3 rounds to ... 630 but libc rounds to ...632. Grisu31359 try testFmt("f64: 1.000", "f64: {d:.3}", .{@as(f64, 1.0)});
1379// // also rounds to 630 so I'm inclined to believe libc is not1360 try testFmt("f64: 0.00030000", "f64: {d:.8}", .{@as(f64, 0.0003)});
1380// // optimal here.1361 try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 1.40130e-45)});
1381// try testFmt("f64: 18014400656965630.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1518338049)))});1362 try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 9.999960e-40)});
1382// }1363}
13831364
1384// test "custom" {1365test "float.libc.sanity" {
1385// const Vec2 = struct {1366 try testFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 916964781)))});
1386// const SelfType = @This();1367 try testFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 925353389)))});
1387// x: f32,1368 try testFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1036831278)))});
1388// y: f32,1369 try testFmt("f64: 1.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1065353133)))});
1370 try testFmt("f64: 10.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1092616192)))});
1371
1372 // libc differences
1373 //
1374 // This is 0.015625 exactly according to gdb. We thus round down,
1375 // however glibc rounds up for some reason. This occurs for all
1376 // floats of the form x.yyyy25 on a precision point.
1377 try testFmt("f64: 0.01563", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1015021568)))});
1378 // errol3 rounds to ... 630 but libc rounds to ...632. Grisu3
1379 // also rounds to 630 so I'm inclined to believe libc is not
1380 // optimal here.
1381 try testFmt("f64: 18014400656965630.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1518338049)))});
1382}
13891383
1390// pub fn format(1384test "custom" {
1391// self: SelfType,1385 const Vec2 = struct {
1392// comptime fmt: []const u8,1386 const SelfType = @This();
1393// options: FormatOptions,1387 x: f32,
1394// context: var,1388 y: f32,
1395// comptime Errors: type,1389
1396// comptime output: fn (@TypeOf(context), []const u8) !void,1390 pub fn format(
1397// ) !void {1391 self: SelfType,
1398// if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "p")) {1392 comptime fmt: []const u8,
1399// return std.fmtstream.format(out_stream, "({d:.3},{d:.3})", .{ self.x, self.y });1393 options: FormatOptions,
1400// } else if (comptime std.mem.eql(u8, fmt, "d")) {1394 out_stream: var,
1401// return std.fmtstream.format(out_stream, "{d:.3}x{d:.3}", .{ self.x, self.y });1395 ) !void {
1402// } else {1396 if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "p")) {
1403// @compileError("Unknown format character: '" ++ fmt ++ "'");1397 return std.fmtstream.format(out_stream, "({d:.3},{d:.3})", .{ self.x, self.y });
1404// }1398 } else if (comptime std.mem.eql(u8, fmt, "d")) {
1405// }1399 return std.fmtstream.format(out_stream, "{d:.3}x{d:.3}", .{ self.x, self.y });
1406// };1400 } else {
1401 @compileError("Unknown format character: '" ++ fmt ++ "'");
1402 }
1403 }
1404 };
14071405
1408// var buf1: [32]u8 = undefined;1406 var buf1: [32]u8 = undefined;
1409// var value = Vec2{1407 var value = Vec2{
1410// .x = 10.2,1408 .x = 10.2,
1411// .y = 2.22,1409 .y = 2.22,
1412// };1410 };
1413// try testFmt("point: (10.200,2.220)\n", "point: {}\n", .{&value});1411 try testFmt("point: (10.200,2.220)\n", "point: {}\n", .{&value});
1414// try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{&value});1412 try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{&value});
14151413
1416// // same thing but not passing a pointer1414 // same thing but not passing a pointer
1417// try testFmt("point: (10.200,2.220)\n", "point: {}\n", .{value});1415 try testFmt("point: (10.200,2.220)\n", "point: {}\n", .{value});
1418// try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{value});1416 try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{value});
1419// }1417}
14201418
1421// test "struct" {1419test "struct" {
1422// const S = struct {1420 const S = struct {
1423// a: u32,1421 a: u32,
1424// b: anyerror,1422 b: anyerror,
1425// };1423 };
14261424
1427// const inst = S{1425 const inst = S{
1428// .a = 456,1426 .a = 456,
1429// .b = error.Unused,1427 .b = error.Unused,
1430// };1428 };
14311429
1432// try testFmt("S{ .a = 456, .b = error.Unused }", "{}", .{inst});1430 try testFmt("S{ .a = 456, .b = error.Unused }", "{}", .{inst});
1433// }1431}
14341432
1435// test "union" {1433test "union" {
1436// const TU = union(enum) {1434 const TU = union(enum) {
1437// float: f32,1435 float: f32,
1438// int: u32,1436 int: u32,
1439// };1437 };
14401438
1441// const UU = union {1439 const UU = union {
1442// float: f32,1440 float: f32,
1443// int: u32,1441 int: u32,
1444// };1442 };
14451443
1446// const EU = extern union {1444 const EU = extern union {
1447// float: f32,1445 float: f32,
1448// int: u32,1446 int: u32,
1449// };1447 };
14501448
1451// const tu_inst = TU{ .int = 123 };1449 const tu_inst = TU{ .int = 123 };
1452// const uu_inst = UU{ .int = 456 };1450 const uu_inst = UU{ .int = 456 };
1453// const eu_inst = EU{ .float = 321.123 };1451 const eu_inst = EU{ .float = 321.123 };
14541452
1455// try testFmt("TU{ .int = 123 }", "{}", .{tu_inst});1453 try testFmt("TU{ .int = 123 }", "{}", .{tu_inst});
14561454
1457// var buf: [100]u8 = undefined;1455 var buf: [100]u8 = undefined;
1458// const uu_result = try bufPrint(buf[0..], "{}", .{uu_inst});1456 const uu_result = try bufPrint(buf[0..], "{}", .{uu_inst});
1459// std.testing.expect(mem.eql(u8, uu_result[0..3], "UU@"));1457 std.testing.expect(mem.eql(u8, uu_result[0..3], "UU@"));
14601458
1461// const eu_result = try bufPrint(buf[0..], "{}", .{eu_inst});1459 const eu_result = try bufPrint(buf[0..], "{}", .{eu_inst});
1462// std.testing.expect(mem.eql(u8, uu_result[0..3], "EU@"));1460 std.testing.expect(mem.eql(u8, uu_result[0..3], "EU@"));
1463// }1461}
14641462
1465// test "enum" {1463test "enum" {
1466// const E = enum {1464 const E = enum {
1467// One,1465 One,
1468// Two,1466 Two,
1469// Three,1467 Three,
1470// };1468 };
14711469
1472// const inst = E.Two;1470 const inst = E.Two;
14731471
1474// try testFmt("E.Two", "{}", .{inst});1472 try testFmt("E.Two", "{}", .{inst});
1475// }1473}
14761474
1477// test "struct.self-referential" {1475// test "struct.self-referential" {
1478// const S = struct {1476// const S = struct {
...@@ -1488,20 +1486,20 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options:...@@ -1488,20 +1486,20 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options:
1488// try testFmt("S{ .a = S{ .a = S{ .a = S{ ... } } } }", "{}", .{inst});1486// try testFmt("S{ .a = S{ .a = S{ .a = S{ ... } } } }", "{}", .{inst});
1489// }1487// }
14901488
1491// test "struct.zero-size" {1489test "struct.zero-size" {
1492// const A = struct {1490 const A = struct {
1493// fn foo() void {}1491 fn foo() void {}
1494// };1492 };
1495// const B = struct {1493 const B = struct {
1496// a: A,1494 a: A,
1497// c: i32,1495 c: i32,
1498// };1496 };
14991497
1500// const a = A{};1498 const a = A{};
1501// const b = B{ .a = a, .c = 0 };1499 const b = B{ .a = a, .c = 0 };
15021500
1503// try testFmt("B{ .a = A{ }, .c = 0 }", "{}", .{b});1501 try testFmt("B{ .a = A{ }, .c = 0 }", "{}", .{b});
1504// }1502}
15051503
1506test "bytes.hex" {1504test "bytes.hex" {
1507 const some_bytes = "\xCA\xFE\xBA\xBE";1505 const some_bytes = "\xCA\xFE\xBA\xBE";
...@@ -1527,66 +1525,66 @@ fn testFmt(expected: []const u8, comptime template: []const u8, args: var) !void...@@ -1527,66 +1525,66 @@ fn testFmt(expected: []const u8, comptime template: []const u8, args: var) !void
1527 return error.TestFailed;1525 return error.TestFailed;
1528}1526}
15291527
1530// pub fn trim(buf: []const u8) []const u8 {1528pub fn trim(buf: []const u8) []const u8 {
1531// var start: usize = 0;1529 var start: usize = 0;
1532// while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) {}1530 while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) {}
15331531
1534// var end: usize = buf.len;1532 var end: usize = buf.len;
1535// while (true) {1533 while (true) {
1536// if (end > start) {1534 if (end > start) {
1537// const new_end = end - 1;1535 const new_end = end - 1;
1538// if (isWhiteSpace(buf[new_end])) {1536 if (isWhiteSpace(buf[new_end])) {
1539// end = new_end;1537 end = new_end;
1540// continue;1538 continue;
1541// }1539 }
1542// }1540 }
1543// break;1541 break;
1544// }1542 }
1545// return buf[start..end];1543 return buf[start..end];
1546// }1544}
15471545
1548// test "trim" {1546test "trim" {
1549// std.testing.expect(mem.eql(u8, "abc", trim("\n abc \t")));1547 std.testing.expect(mem.eql(u8, "abc", trim("\n abc \t")));
1550// std.testing.expect(mem.eql(u8, "", trim(" ")));1548 std.testing.expect(mem.eql(u8, "", trim(" ")));
1551// std.testing.expect(mem.eql(u8, "", trim("")));1549 std.testing.expect(mem.eql(u8, "", trim("")));
1552// std.testing.expect(mem.eql(u8, "abc", trim(" abc")));1550 std.testing.expect(mem.eql(u8, "abc", trim(" abc")));
1553// std.testing.expect(mem.eql(u8, "abc", trim("abc ")));1551 std.testing.expect(mem.eql(u8, "abc", trim("abc ")));
1554// }1552}
15551553
1556// pub fn isWhiteSpace(byte: u8) bool {1554pub fn isWhiteSpace(byte: u8) bool {
1557// return switch (byte) {1555 return switch (byte) {
1558// ' ', '\t', '\n', '\r' => true,1556 ' ', '\t', '\n', '\r' => true,
1559// else => false,1557 else => false,
1560// };1558 };
1561// }1559}
15621560
1563// pub fn hexToBytes(out: []u8, input: []const u8) !void {1561pub fn hexToBytes(out: []u8, input: []const u8) !void {
1564// if (out.len * 2 < input.len)1562 if (out.len * 2 < input.len)
1565// return error.InvalidLength;1563 return error.InvalidLength;
15661564
1567// var in_i: usize = 0;1565 var in_i: usize = 0;
1568// while (in_i != input.len) : (in_i += 2) {1566 while (in_i != input.len) : (in_i += 2) {
1569// const hi = try charToDigit(input[in_i], 16);1567 const hi = try charToDigit(input[in_i], 16);
1570// const lo = try charToDigit(input[in_i + 1], 16);1568 const lo = try charToDigit(input[in_i + 1], 16);
1571// out[in_i / 2] = (hi << 4) | lo;1569 out[in_i / 2] = (hi << 4) | lo;
1572// }1570 }
1573// }1571}
15741572
1575// test "hexToBytes" {1573test "hexToBytes" {
1576// const test_hex_str = "909A312BB12ED1F819B3521AC4C1E896F2160507FFC1C8381E3B07BB16BD1706";1574 const test_hex_str = "909A312BB12ED1F819B3521AC4C1E896F2160507FFC1C8381E3B07BB16BD1706";
1577// var pb: [32]u8 = undefined;1575 var pb: [32]u8 = undefined;
1578// try hexToBytes(pb[0..], test_hex_str);1576 try hexToBytes(pb[0..], test_hex_str);
1579// try testFmt(test_hex_str, "{X}", .{pb});1577 try testFmt(test_hex_str, "{X}", .{pb});
1580// }1578}
15811579
1582// test "formatIntValue with comptime_int" {1580test "formatIntValue with comptime_int" {
1583// const value: comptime_int = 123456789123456789;1581 const value: comptime_int = 123456789123456789;
15841582
1585// var buf = std.ArrayList(u8).init(std.testing.allocator);1583 var buf: [20]u8 = undefined;
1586// defer buf.deinit();1584 var fbs = std.io.fixedBufferStream(&buf);
1587// try formatIntValue(value, "", FormatOptions{}, &buf, @TypeOf(std.ArrayList(u8).appendSlice).ReturnType.ErrorSet, std.ArrayList(u8).appendSlice);1585 try formatIntValue(value, "", FormatOptions{}, fbs.outStream());
1588// std.testing.expect(mem.eql(u8, buf.toSliceConst(), "123456789123456789"));1586 std.testing.expect(mem.eql(u8, buf[0..fbs.pos], "123456789123456789"));
1589// }1587}
15901588
1591// test "formatType max_depth" {1589// test "formatType max_depth" {
1592// const Vec2 = struct {1590// const Vec2 = struct {
...@@ -1658,39 +1656,39 @@ fn testFmt(expected: []const u8, comptime template: []const u8, args: var) !void...@@ -1658,39 +1656,39 @@ fn testFmt(expected: []const u8, comptime template: []const u8, args: var) !void
1658// 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) }"));1656// 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) }"));
1659// }1657// }
16601658
1661// test "positional" {1659test "positional" {
1662// try testFmt("2 1 0", "{2} {1} {0}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) });1660 try testFmt("2 1 0", "{2} {1} {0}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) });
1663// try testFmt("2 1 0", "{2} {1} {}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) });1661 try testFmt("2 1 0", "{2} {1} {}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) });
1664// try testFmt("0 0", "{0} {0}", .{@as(usize, 0)});1662 try testFmt("0 0", "{0} {0}", .{@as(usize, 0)});
1665// try testFmt("0 1", "{} {1}", .{ @as(usize, 0), @as(usize, 1) });1663 try testFmt("0 1", "{} {1}", .{ @as(usize, 0), @as(usize, 1) });
1666// try testFmt("1 0 0 1", "{1} {} {0} {}", .{ @as(usize, 0), @as(usize, 1) });1664 try testFmt("1 0 0 1", "{1} {} {0} {}", .{ @as(usize, 0), @as(usize, 1) });
1667// }1665}
16681666
1669// test "positional with specifier" {1667test "positional with specifier" {
1670// try testFmt("10.0", "{0d:.1}", .{@as(f64, 9.999)});1668 try testFmt("10.0", "{0d:.1}", .{@as(f64, 9.999)});
1671// }1669}
16721670
1673// test "positional/alignment/width/precision" {1671test "positional/alignment/width/precision" {
1674// try testFmt("10.0", "{0d: >3.1}", .{@as(f64, 9.999)});1672 try testFmt("10.0", "{0d: >3.1}", .{@as(f64, 9.999)});
1675// }1673}
16761674
1677// test "vector" {1675test "vector" {
1678// // https://github.com/ziglang/zig/issues/33171676 // https://github.com/ziglang/zig/issues/3317
1679// if (builtin.arch == .mipsel) return error.SkipZigTest;1677 if (builtin.arch == .mipsel) return error.SkipZigTest;
16801678
1681// const vbool: @Vector(4, bool) = [_]bool{ true, false, true, false };1679 const vbool: @Vector(4, bool) = [_]bool{ true, false, true, false };
1682// const vi64: @Vector(4, i64) = [_]i64{ -2, -1, 0, 1 };1680 const vi64: @Vector(4, i64) = [_]i64{ -2, -1, 0, 1 };
1683// const vu64: @Vector(4, u64) = [_]u64{ 1000, 2000, 3000, 4000 };1681 const vu64: @Vector(4, u64) = [_]u64{ 1000, 2000, 3000, 4000 };
16841682
1685// try testFmt("{ true, false, true, false }", "{}", .{vbool});1683 try testFmt("{ true, false, true, false }", "{}", .{vbool});
1686// try testFmt("{ -2, -1, 0, 1 }", "{}", .{vi64});1684 try testFmt("{ -2, -1, 0, 1 }", "{}", .{vi64});
1687// try testFmt("{ - 2, - 1, + 0, + 1 }", "{d:5}", .{vi64});1685 try testFmt("{ - 2, - 1, + 0, + 1 }", "{d:5}", .{vi64});
1688// try testFmt("{ 1000, 2000, 3000, 4000 }", "{}", .{vu64});1686 try testFmt("{ 1000, 2000, 3000, 4000 }", "{}", .{vu64});
1689// try testFmt("{ 3e8, 7d0, bb8, fa0 }", "{x}", .{vu64});1687 try testFmt("{ 3e8, 7d0, bb8, fa0 }", "{x}", .{vu64});
1690// try testFmt("{ 1kB, 2kB, 3kB, 4kB }", "{B}", .{vu64});1688 try testFmt("{ 1kB, 2kB, 3kB, 4kB }", "{B}", .{vu64});
1691// try testFmt("{ 1000B, 1.953125KiB, 2.9296875KiB, 3.90625KiB }", "{Bi}", .{vu64});1689 try testFmt("{ 1000B, 1.953125KiB, 2.9296875KiB, 3.90625KiB }", "{Bi}", .{vu64});
1692// }1690}
16931691
1694// test "enum-literal" {1692test "enum-literal" {
1695// try testFmt(".hello_world", "{}", .{.hello_world});1693 try testFmt(".hello_world", "{}", .{.hello_world});
1696// }1694}