| author | |
| committer | |
| log | 6e987a1d04e5d9eb41a10110a5343384f0a9a57b |
| tree | f82b5fe8e3e17c50628ae0b9a3c46ecdfca6e2ae |
| parent | b0ef8d3610ab18eb499eb351e302ecc3ab5aea78 |
| parent | 6612e7cdb26a761392f129525872bd00758095c2 |
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31923
Reviewed-by: Andrew Kelley <andrew@ziglang.org>24 files changed, 621 insertions(+), 445 deletions(-)
build.zig+16-16| ... | ... | @@ -526,16 +526,16 @@ pub fn build(b: *std.Build) !void { |
| 526 | 526 | .test_filters = test_filters, |
| 527 | 527 | .test_target_filters = test_target_filters, |
| 528 | 528 | .test_extra_targets = test_extra_targets, |
| 529 | .root_src = "lib/c.zig", | |
| 530 | .name = "zigc", | |
| 531 | .desc = "Run the zig libc implementation unit tests", | |
| 529 | .root_src = "lib/std/std.zig", | |
| 530 | .name = "std", | |
| 531 | .desc = "Run the standard library tests", | |
| 532 | 532 | .optimize_modes = optimization_modes, |
| 533 | 533 | .include_paths = &.{}, |
| 534 | 534 | .sanitize_thread = sanitize_thread, |
| 535 | .skip_single_threaded = true, | |
| 535 | .skip_single_threaded = skip_single_threaded, | |
| 536 | 536 | .skip_non_native = skip_non_native, |
| 537 | 537 | .test_only = test_only, |
| 538 | .skip_spirv = skip_spirv, | |
| 538 | .skip_spirv = true, | |
| 539 | 539 | .skip_wasm = skip_wasm, |
| 540 | 540 | .skip_freebsd = skip_freebsd, |
| 541 | 541 | .skip_netbsd = skip_netbsd, |
| ... | ... | @@ -544,25 +544,24 @@ pub fn build(b: *std.Build) !void { |
| 544 | 544 | .skip_darwin = skip_darwin, |
| 545 | 545 | .skip_linux = skip_linux, |
| 546 | 546 | .skip_llvm = skip_llvm, |
| 547 | .skip_libc = true, | |
| 548 | .no_builtin = true, | |
| 549 | .max_rss = 4_000_000_000, | |
| 547 | .skip_libc = skip_libc, | |
| 548 | .max_rss = 9_300_000_000, | |
| 550 | 549 | })); |
| 551 | 550 | |
| 552 | 551 | test_modules_step.dependOn(tests.addModuleTests(b, .{ |
| 553 | 552 | .test_filters = test_filters, |
| 554 | 553 | .test_target_filters = test_target_filters, |
| 555 | 554 | .test_extra_targets = test_extra_targets, |
| 556 | .root_src = "lib/std/std.zig", | |
| 557 | .name = "std", | |
| 558 | .desc = "Run the standard library tests", | |
| 555 | .root_src = "test/c.zig", | |
| 556 | .name = "libc", | |
| 557 | .desc = "Run the libc API tests", | |
| 559 | 558 | .optimize_modes = optimization_modes, |
| 560 | 559 | .include_paths = &.{}, |
| 561 | 560 | .sanitize_thread = sanitize_thread, |
| 562 | .skip_single_threaded = skip_single_threaded, | |
| 561 | .skip_single_threaded = true, | |
| 563 | 562 | .skip_non_native = skip_non_native, |
| 564 | 563 | .test_only = test_only, |
| 565 | .skip_spirv = skip_spirv, | |
| 564 | .skip_spirv = true, | |
| 566 | 565 | .skip_wasm = skip_wasm, |
| 567 | 566 | .skip_freebsd = skip_freebsd, |
| 568 | 567 | .skip_netbsd = skip_netbsd, |
| ... | ... | @@ -572,7 +571,8 @@ pub fn build(b: *std.Build) !void { |
| 572 | 571 | .skip_linux = skip_linux, |
| 573 | 572 | .skip_llvm = skip_llvm, |
| 574 | 573 | .skip_libc = skip_libc, |
| 575 | .max_rss = 9_300_000_000, | |
| 574 | .no_builtin = true, | |
| 575 | .max_rss = 4_000_000_000, | |
| 576 | 576 | })); |
| 577 | 577 | |
| 578 | 578 | const unit_tests_step = b.step("test-unit", "Run the compiler source unit tests"); |
| ... | ... | @@ -662,13 +662,13 @@ pub fn build(b: *std.Build) !void { |
| 662 | 662 | try tests.addIncrementalTests(b, test_incremental_step, test_filters); |
| 663 | 663 | if (!skip_test_incremental) test_step.dependOn(test_incremental_step); |
| 664 | 664 | |
| 665 | if (tests.addLibcTests(b, .{ | |
| 665 | if (tests.addLibcTestNszTests(b, .{ | |
| 666 | 666 | .optimize_modes = optimization_modes, |
| 667 | 667 | .test_filters = test_filters, |
| 668 | 668 | .test_target_filters = test_target_filters, |
| 669 | 669 | .skip_wasm = skip_wasm, |
| 670 | 670 | .max_rss = 3_500_000_000, |
| 671 | })) |test_libc_step| test_step.dependOn(test_libc_step); | |
| 671 | })) |test_libc_nsz_step| test_step.dependOn(test_libc_nsz_step); | |
| 672 | 672 | } |
| 673 | 673 | |
| 674 | 674 | fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { |
lib/c.zig+1-2| ... | ... | @@ -2,8 +2,7 @@ |
| 2 | 2 | //! bundled libcs. |
| 3 | 3 | //! |
| 4 | 4 | //! mingw-w64 libc is not fully statically linked, so some symbols don't need |
| 5 | //! to be exported. However, a future enhancement could be eliminating Zig's | |
| 6 | //! dependency on msvcrt dll even when linking libc and targeting Windows. | |
| 5 | //! to be exported. | |
| 7 | 6 | |
| 8 | 7 | const builtin = @import("builtin"); |
| 9 | 8 | const std = @import("std"); |
lib/c/inttypes.zig-10| ... | ... | @@ -24,13 +24,3 @@ fn imaxdiv(a: intmax_t, b: intmax_t) callconv(.c) imaxdiv_t { |
| 24 | 24 | .rem = @rem(a, b), |
| 25 | 25 | }; |
| 26 | 26 | } |
| 27 | ||
| 28 | test imaxabs { | |
| 29 | const val: intmax_t = -10; | |
| 30 | try std.testing.expectEqual(10, imaxabs(val)); | |
| 31 | } | |
| 32 | ||
| 33 | test imaxdiv { | |
| 34 | const expected: imaxdiv_t = .{ .quot = 9, .rem = 0 }; | |
| 35 | try std.testing.expectEqual(expected, imaxdiv(9, 1)); | |
| 36 | } |
lib/c/math.zig-100| ... | ... | @@ -2,10 +2,6 @@ const builtin = @import("builtin"); |
| 2 | 2 | |
| 3 | 3 | const std = @import("std"); |
| 4 | 4 | const math = std.math; |
| 5 | const expect = std.testing.expect; | |
| 6 | const expectEqual = std.testing.expectEqual; | |
| 7 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; | |
| 8 | const expectApproxEqRel = std.testing.expectApproxEqRel; | |
| 9 | 5 | |
| 10 | 6 | const symbol = @import("../c.zig").symbol; |
| 11 | 7 | |
| ... | ... | @@ -304,59 +300,6 @@ fn modfl(x: c_longdouble, iptr: *c_longdouble) callconv(.c) c_longdouble { |
| 304 | 300 | }; |
| 305 | 301 | } |
| 306 | 302 | |
| 307 | fn testModf(comptime T: type) !void { | |
| 308 | // Choose the appropriate `modf` impl to test based on type | |
| 309 | const f = switch (T) { | |
| 310 | f32 => modff, | |
| 311 | f64 => modf, | |
| 312 | c_longdouble => modfl, | |
| 313 | else => @compileError("modf not implemented for " ++ @typeName(T)), | |
| 314 | }; | |
| 315 | ||
| 316 | var int: T = undefined; | |
| 317 | const iptr = &int; | |
| 318 | const eps_val: comptime_float = @max(1e-6, math.floatEps(T)); | |
| 319 | ||
| 320 | const normal_frac = f(@as(T, 1234.567), iptr); | |
| 321 | // Account for precision error | |
| 322 | const expected = 1234.567 - @as(T, 1234); | |
| 323 | try expectApproxEqAbs(expected, normal_frac, eps_val); | |
| 324 | try expectApproxEqRel(@as(T, 1234.0), iptr.*, eps_val); | |
| 325 | ||
| 326 | // When `x` is a NaN, NaN is returned and `*iptr` is set to NaN | |
| 327 | const nan_frac = f(math.nan(T), iptr); | |
| 328 | try expect(math.isNan(nan_frac)); | |
| 329 | try expect(math.isNan(iptr.*)); | |
| 330 | ||
| 331 | // When `x` is positive infinity, +0 is returned and `*iptr` is set to | |
| 332 | // positive infinity | |
| 333 | const pos_zero_frac = f(math.inf(T), iptr); | |
| 334 | try expect(math.isPositiveZero(pos_zero_frac)); | |
| 335 | try expect(math.isPositiveInf(iptr.*)); | |
| 336 | ||
| 337 | // When `x` is negative infinity, -0 is returned and `*iptr` is set to | |
| 338 | // negative infinity | |
| 339 | const neg_zero_frac = f(-math.inf(T), iptr); | |
| 340 | try expect(math.isNegativeZero(neg_zero_frac)); | |
| 341 | try expect(math.isNegativeInf(iptr.*)); | |
| 342 | ||
| 343 | // Return -0 when `x` is a negative integer | |
| 344 | const nz_frac = f(@as(T, -1000.0), iptr); | |
| 345 | try expect(math.isNegativeZero(nz_frac)); | |
| 346 | try expectEqual(@as(T, -1000.0), iptr.*); | |
| 347 | ||
| 348 | // Return +0 when `x` is a positive integer | |
| 349 | const pz_frac = f(@as(T, 1000.0), iptr); | |
| 350 | try expect(math.isPositiveZero(pz_frac)); | |
| 351 | try expectEqual(@as(T, 1000.0), iptr.*); | |
| 352 | } | |
| 353 | ||
| 354 | test "modf" { | |
| 355 | try testModf(f32); | |
| 356 | try testModf(f64); | |
| 357 | try testModf(c_longdouble); | |
| 358 | } | |
| 359 | ||
| 360 | 303 | fn nan(_: [*:0]const c_char) callconv(.c) f64 { |
| 361 | 304 | return math.nan(f64); |
| 362 | 305 | } |
| ... | ... | @@ -421,49 +364,6 @@ fn rintf(x: f32) callconv(.c) f32 { |
| 421 | 364 | return y; |
| 422 | 365 | } |
| 423 | 366 | |
| 424 | fn testRint(comptime T: type) !void { | |
| 425 | const f = switch (T) { | |
| 426 | f32 => rintf, | |
| 427 | f64 => rint, | |
| 428 | else => @compileError("rint not implemented for" ++ @typeName(T)), | |
| 429 | }; | |
| 430 | ||
| 431 | // Positive numbers round correctly | |
| 432 | try expectEqual(@as(T, 42.0), f(42.2)); | |
| 433 | try expectEqual(@as(T, 42.0), f(41.8)); | |
| 434 | ||
| 435 | // Negative numbers round correctly | |
| 436 | try expectEqual(@as(T, -6.0), f(-5.9)); | |
| 437 | try expectEqual(@as(T, -6.0), f(-6.1)); | |
| 438 | ||
| 439 | // No rounding needed test | |
| 440 | try expectEqual(@as(T, 5.0), f(5.0)); | |
| 441 | try expectEqual(@as(T, -10.0), f(-10.0)); | |
| 442 | try expectEqual(@as(T, 0.0), f(0.0)); | |
| 443 | ||
| 444 | // Very large numbers return unchanged | |
| 445 | const large: T = 9007199254740992.0; // 2^53 | |
| 446 | try expectEqual(large, f(large)); | |
| 447 | try expectEqual(-large, f(-large)); | |
| 448 | ||
| 449 | // Small positive numbers round to zero | |
| 450 | const pos_result = f(0.3); | |
| 451 | try expect(math.isPositiveZero(pos_result)); | |
| 452 | ||
| 453 | // Small negative numbers round to negative zero | |
| 454 | const neg_result = f(-0.3); | |
| 455 | try expect(math.isNegativeZero(neg_result)); | |
| 456 | ||
| 457 | // Exact half rounds to nearest even (banker's rounding) | |
| 458 | try expectEqual(@as(T, 2.0), f(2.5)); | |
| 459 | try expectEqual(@as(T, 4.0), f(3.5)); | |
| 460 | } | |
| 461 | ||
| 462 | test "rint" { | |
| 463 | try testRint(f32); | |
| 464 | try testRint(f64); | |
| 465 | } | |
| 466 | ||
| 467 | 367 | fn tanh(x: f64) callconv(.c) f64 { |
| 468 | 368 | return math.tanh(x); |
| 469 | 369 | } |
lib/c/search.zig+1-27| ... | ... | @@ -9,6 +9,7 @@ comptime { |
| 9 | 9 | } |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | /// Not defined in `std.c` because C headers don't either. | |
| 12 | 13 | const Node = extern struct { |
| 13 | 14 | next: ?*Node, |
| 14 | 15 | prev: ?*Node, |
| ... | ... | @@ -38,30 +39,3 @@ fn remque(element: *anyopaque) callconv(.c) void { |
| 38 | 39 | if (e.next) |next| next.prev = e.prev; |
| 39 | 40 | if (e.prev) |prev| prev.next = e.next; |
| 40 | 41 | } |
| 41 | ||
| 42 | test "insque and remque" { | |
| 43 | var first = Node{ .next = null, .prev = null }; | |
| 44 | var second = Node{ .next = null, .prev = null }; | |
| 45 | var third = Node{ .next = null, .prev = null }; | |
| 46 | ||
| 47 | insque(&first, null); | |
| 48 | try std.testing.expectEqual(@as(?*Node, null), first.next); | |
| 49 | try std.testing.expectEqual(@as(?*Node, null), first.prev); | |
| 50 | ||
| 51 | insque(&second, &first); | |
| 52 | try std.testing.expectEqual(@as(?*Node, &second), first.next); | |
| 53 | try std.testing.expectEqual(@as(?*Node, &first), second.prev); | |
| 54 | ||
| 55 | insque(&third, &first); | |
| 56 | try std.testing.expectEqual(@as(?*Node, &third), first.next); | |
| 57 | try std.testing.expectEqual(@as(?*Node, &second), third.next); | |
| 58 | try std.testing.expectEqual(@as(?*Node, &first), third.prev); | |
| 59 | try std.testing.expectEqual(@as(?*Node, &third), second.prev); | |
| 60 | ||
| 61 | remque(&third); | |
| 62 | try std.testing.expectEqual(@as(?*Node, &second), first.next); | |
| 63 | try std.testing.expectEqual(@as(?*Node, &first), second.prev); | |
| 64 | ||
| 65 | remque(&second); | |
| 66 | try std.testing.expectEqual(@as(?*Node, null), first.next); | |
| 67 | } |
lib/c/stdlib.zig-100| ... | ... | @@ -294,103 +294,3 @@ fn bsearch(key: *const anyopaque, base: *const anyopaque, n: usize, size: usize, |
| 294 | 294 | } |
| 295 | 295 | return null; |
| 296 | 296 | } |
| 297 | ||
| 298 | test abs { | |
| 299 | const val: c_int = -10; | |
| 300 | try std.testing.expectEqual(10, abs(val)); | |
| 301 | } | |
| 302 | ||
| 303 | test labs { | |
| 304 | const val: c_long = -10; | |
| 305 | try std.testing.expectEqual(10, labs(val)); | |
| 306 | } | |
| 307 | ||
| 308 | test llabs { | |
| 309 | const val: c_longlong = -10; | |
| 310 | try std.testing.expectEqual(10, llabs(val)); | |
| 311 | } | |
| 312 | ||
| 313 | test div { | |
| 314 | const expected: div_t = .{ .quot = 5, .rem = 5 }; | |
| 315 | try std.testing.expectEqual(expected, div(55, 10)); | |
| 316 | } | |
| 317 | ||
| 318 | test ldiv { | |
| 319 | const expected: ldiv_t = .{ .quot = -6, .rem = 2 }; | |
| 320 | try std.testing.expectEqual(expected, ldiv(38, -6)); | |
| 321 | } | |
| 322 | ||
| 323 | test lldiv { | |
| 324 | const expected: lldiv_t = .{ .quot = 1, .rem = 2 }; | |
| 325 | try std.testing.expectEqual(expected, lldiv(5, 3)); | |
| 326 | } | |
| 327 | ||
| 328 | test atoi { | |
| 329 | try std.testing.expectEqual(0, atoi(@ptrCast("stop42true"))); | |
| 330 | try std.testing.expectEqual(42, atoi(@ptrCast("42true"))); | |
| 331 | try std.testing.expectEqual(-1, atoi(@ptrCast("-01"))); | |
| 332 | try std.testing.expectEqual(1, atoi(@ptrCast("+001"))); | |
| 333 | try std.testing.expectEqual(100, atoi(@ptrCast(" 100"))); | |
| 334 | try std.testing.expectEqual(500, atoi(@ptrCast("000000000000500"))); | |
| 335 | try std.testing.expectEqual(1111, atoi(@ptrCast("0000000000001111_0000"))); | |
| 336 | try std.testing.expectEqual(0, atoi(@ptrCast("0xAA"))); | |
| 337 | try std.testing.expectEqual(700, atoi(@ptrCast("700B"))); | |
| 338 | try std.testing.expectEqual(32453, atoi(@ptrCast("+32453more"))); | |
| 339 | try std.testing.expectEqual(std.math.maxInt(c_int), atoi(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.maxInt(c_int)})))); | |
| 340 | try std.testing.expectEqual(std.math.minInt(c_int), atoi(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.minInt(c_int)})))); | |
| 341 | } | |
| 342 | ||
| 343 | test atol { | |
| 344 | try std.testing.expectEqual(0, atol(@ptrCast("stop42true"))); | |
| 345 | try std.testing.expectEqual(42, atol(@ptrCast("42true"))); | |
| 346 | try std.testing.expectEqual(-1, atol(@ptrCast("-01"))); | |
| 347 | try std.testing.expectEqual(1, atol(@ptrCast("+001"))); | |
| 348 | try std.testing.expectEqual(100, atol(@ptrCast(" 100"))); | |
| 349 | try std.testing.expectEqual(500, atol(@ptrCast("000000000000500"))); | |
| 350 | try std.testing.expectEqual(1111, atol(@ptrCast("0000000000001111_0000"))); | |
| 351 | try std.testing.expectEqual(0, atol(@ptrCast("0xAA"))); | |
| 352 | try std.testing.expectEqual(700, atol(@ptrCast("700B"))); | |
| 353 | try std.testing.expectEqual(32453, atol(@ptrCast("+32453more"))); | |
| 354 | try std.testing.expectEqual(std.math.maxInt(c_long), atol(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.maxInt(c_long)})))); | |
| 355 | try std.testing.expectEqual(std.math.minInt(c_long), atol(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.minInt(c_long)})))); | |
| 356 | } | |
| 357 | ||
| 358 | test atoll { | |
| 359 | try std.testing.expectEqual(0, atoll(@ptrCast("stop42true"))); | |
| 360 | try std.testing.expectEqual(42, atoll(@ptrCast("42true"))); | |
| 361 | try std.testing.expectEqual(-1, atoll(@ptrCast("-01"))); | |
| 362 | try std.testing.expectEqual(1, atoll(@ptrCast("+001"))); | |
| 363 | try std.testing.expectEqual(100, atoll(@ptrCast(" 100"))); | |
| 364 | try std.testing.expectEqual(500, atoll(@ptrCast("000000000000500"))); | |
| 365 | try std.testing.expectEqual(1111, atoll(@ptrCast("0000000000001111_0000"))); | |
| 366 | try std.testing.expectEqual(0, atoll(@ptrCast("0xAA"))); | |
| 367 | try std.testing.expectEqual(700, atoll(@ptrCast("700B"))); | |
| 368 | try std.testing.expectEqual(32453, atoll(@ptrCast(" +32453more"))); | |
| 369 | try std.testing.expectEqual(std.math.maxInt(c_longlong), atoll(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.maxInt(c_longlong)})))); | |
| 370 | try std.testing.expectEqual(std.math.minInt(c_longlong), atoll(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.minInt(c_longlong)})))); | |
| 371 | } | |
| 372 | ||
| 373 | // FIXME: We cannot test strtol, strtoll, strtoul, etc.. here as it must modify errno and libc is not linked in tests | |
| 374 | ||
| 375 | test bsearch { | |
| 376 | const Comparison = struct { | |
| 377 | pub fn compare(a: *const anyopaque, b: *const anyopaque) callconv(.c) c_int { | |
| 378 | const a_u16: *const u16 = @ptrCast(@alignCast(a)); | |
| 379 | const b_u16: *const u16 = @ptrCast(@alignCast(b)); | |
| 380 | ||
| 381 | return switch (std.math.order(a_u16.*, b_u16.*)) { | |
| 382 | .gt => 1, | |
| 383 | .eq => 0, | |
| 384 | .lt => -1, | |
| 385 | }; | |
| 386 | } | |
| 387 | }; | |
| 388 | ||
| 389 | const items: []const u16 = &.{ 0, 5, 7, 9, 10, 200, 512, 768 }; | |
| 390 | ||
| 391 | try std.testing.expectEqual(@as(?*anyopaque, null), bsearch(&@as(u16, 2000), items.ptr, items.len, @sizeOf(u16), Comparison.compare)); | |
| 392 | ||
| 393 | for (items) |*value| { | |
| 394 | try std.testing.expectEqual(@as(*const anyopaque, value), bsearch(value, items.ptr, items.len, @sizeOf(u16), Comparison.compare)); | |
| 395 | } | |
| 396 | } |
lib/c/stdlib/drand48.zig-57| ... | ... | @@ -90,60 +90,3 @@ fn srand48(seedval: c_long) callconv(.c) void { |
| 90 | 90 | const xi = (@as(u32, @truncate(@as(c_ulong, @bitCast(seedval)))) << 16) | 0x330E; |
| 91 | 91 | lcg = .init(xi, default_multiplier, default_addend); |
| 92 | 92 | } |
| 93 | ||
| 94 | test erand48 { | |
| 95 | var xsubi: [3]c_ushort = .{ 37174, 64810, 11603 }; | |
| 96 | ||
| 97 | try std.testing.expectApproxEqAbs(0.8965, erand48(&xsubi), 0.0005); | |
| 98 | try std.testing.expectEqualSlices(c_ushort, &.{ 22537, 47966, 58735 }, &xsubi); | |
| 99 | ||
| 100 | try std.testing.expectApproxEqAbs(0.3375, erand48(&xsubi), 0.0005); | |
| 101 | try std.testing.expectEqualSlices(c_ushort, &.{ 37344, 32911, 22119 }, &xsubi); | |
| 102 | ||
| 103 | try std.testing.expectApproxEqAbs(0.6475, erand48(&xsubi), 0.0005); | |
| 104 | try std.testing.expectEqualSlices(c_ushort, &.{ 23659, 29872, 42445 }, &xsubi); | |
| 105 | ||
| 106 | try std.testing.expectApproxEqAbs(0.5005, erand48(&xsubi), 0.0005); | |
| 107 | try std.testing.expectEqualSlices(c_ushort, &.{ 31642, 7875, 32802 }, &xsubi); | |
| 108 | ||
| 109 | try std.testing.expectApproxEqAbs(0.5065, erand48(&xsubi), 0.0005); | |
| 110 | try std.testing.expectEqualSlices(c_ushort, &.{ 64669, 14399, 33170 }, &xsubi); | |
| 111 | } | |
| 112 | ||
| 113 | test jrand48 { | |
| 114 | var xsubi: [3]c_ushort = .{ 25175, 11052, 45015 }; | |
| 115 | ||
| 116 | try std.testing.expectEqual(1699503220, jrand48(&xsubi)); | |
| 117 | try std.testing.expectEqualSlices(c_ushort, &.{ 2326, 23668, 25932 }, &xsubi); | |
| 118 | ||
| 119 | try std.testing.expectEqual(-992276007, jrand48(&xsubi)); | |
| 120 | try std.testing.expectEqualSlices(c_ushort, &.{ 41577, 4569, 50395 }, &xsubi); | |
| 121 | ||
| 122 | try std.testing.expectEqual(-19535776, jrand48(&xsubi)); | |
| 123 | try std.testing.expectEqualSlices(c_ushort, &.{ 31936, 59488, 65237 }, &xsubi); | |
| 124 | ||
| 125 | try std.testing.expectEqual(79438377, jrand48(&xsubi)); | |
| 126 | try std.testing.expectEqualSlices(c_ushort, &.{ 40395, 8745, 1212 }, &xsubi); | |
| 127 | ||
| 128 | try std.testing.expectEqual(-1258917728, jrand48(&xsubi)); | |
| 129 | try std.testing.expectEqualSlices(c_ushort, &.{ 37242, 28832, 46326 }, &xsubi); | |
| 130 | } | |
| 131 | ||
| 132 | test nrand48 { | |
| 133 | var xsubi: [3]c_ushort = .{ 546, 33817, 23389 }; | |
| 134 | ||
| 135 | try std.testing.expectEqual(914920692, nrand48(&xsubi)); | |
| 136 | try std.testing.expectEqualSlices(c_ushort, &.{ 29829, 10728, 27921 }, &xsubi); | |
| 137 | ||
| 138 | try std.testing.expectEqual(754104482, nrand48(&xsubi)); | |
| 139 | try std.testing.expectEqualSlices(c_ushort, &.{ 6828, 28997, 23013 }, &xsubi); | |
| 140 | ||
| 141 | try std.testing.expectEqual(609453945, nrand48(&xsubi)); | |
| 142 | try std.testing.expectEqualSlices(c_ushort, &.{ 58183, 3826, 18599 }, &xsubi); | |
| 143 | ||
| 144 | try std.testing.expectEqual(1878644360, nrand48(&xsubi)); | |
| 145 | try std.testing.expectEqualSlices(c_ushort, &.{ 36678, 44304, 57331 }, &xsubi); | |
| 146 | ||
| 147 | try std.testing.expectEqual(2114923686, nrand48(&xsubi)); | |
| 148 | try std.testing.expectEqualSlices(c_ushort, &.{ 58585, 22861, 64542 }, &xsubi); | |
| 149 | } |
lib/c/string.zig-7| ... | ... | @@ -290,10 +290,3 @@ fn mempcpy(noalias dst: *anyopaque, noalias src: *const anyopaque, len: usize) c |
| 290 | 290 | @memcpy(dst_bytes[0..len], src_bytes[0..len]); |
| 291 | 291 | return dst_bytes + len; |
| 292 | 292 | } |
| 293 | ||
| 294 | test strncmp { | |
| 295 | try std.testing.expect(strncmp(@ptrCast("a"), @ptrCast("b"), 1) < 0); | |
| 296 | try std.testing.expect(strncmp(@ptrCast("a"), @ptrCast("c"), 1) < 0); | |
| 297 | try std.testing.expect(strncmp(@ptrCast("b"), @ptrCast("a"), 1) > 0); | |
| 298 | try std.testing.expect(strncmp(@ptrCast("\xff"), @ptrCast("\x02"), 1) > 0); | |
| 299 | } |
lib/c/strings.zig-38| ... | ... | @@ -81,41 +81,3 @@ fn __strncasecmp_l(a: [*:0]const c_char, b: [*:0]const c_char, n: usize, locale: |
| 81 | 81 | _ = locale; |
| 82 | 82 | return strncasecmp(a, b, n); |
| 83 | 83 | } |
| 84 | ||
| 85 | test bzero { | |
| 86 | var array: [10]u8 = [_]u8{ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' }; | |
| 87 | var a = std.mem.zeroes([array.len]u8); | |
| 88 | a[9] = '0'; | |
| 89 | bzero(&array[0], 9); | |
| 90 | try std.testing.expect(std.mem.eql(u8, &array, &a)); | |
| 91 | } | |
| 92 | ||
| 93 | test firstBitSet { | |
| 94 | try std.testing.expectEqual(0, firstBitSet(usize, 0)); | |
| 95 | ||
| 96 | for (0..@bitSizeOf(usize)) |i| { | |
| 97 | const bit = @as(usize, 1) << @intCast(i); | |
| 98 | ||
| 99 | try std.testing.expectEqual(i + 1, firstBitSet(usize, bit)); | |
| 100 | } | |
| 101 | } | |
| 102 | ||
| 103 | test strcasecmp { | |
| 104 | try std.testing.expect(strcasecmp(@ptrCast("a"), @ptrCast("b")) < 0); | |
| 105 | try std.testing.expect(strcasecmp(@ptrCast("b"), @ptrCast("a")) > 0); | |
| 106 | try std.testing.expect(strcasecmp(@ptrCast("A"), @ptrCast("b")) < 0); | |
| 107 | try std.testing.expect(strcasecmp(@ptrCast("b"), @ptrCast("A")) > 0); | |
| 108 | try std.testing.expect(strcasecmp(@ptrCast("A"), @ptrCast("A")) == 0); | |
| 109 | try std.testing.expect(strcasecmp(@ptrCast("B"), @ptrCast("b")) == 0); | |
| 110 | try std.testing.expect(strcasecmp(@ptrCast("bb"), @ptrCast("AA")) > 0); | |
| 111 | } | |
| 112 | ||
| 113 | test strncasecmp { | |
| 114 | try std.testing.expect(strncasecmp(@ptrCast("a"), @ptrCast("b"), 1) < 0); | |
| 115 | try std.testing.expect(strncasecmp(@ptrCast("b"), @ptrCast("a"), 1) > 0); | |
| 116 | try std.testing.expect(strncasecmp(@ptrCast("A"), @ptrCast("b"), 1) < 0); | |
| 117 | try std.testing.expect(strncasecmp(@ptrCast("b"), @ptrCast("A"), 1) > 0); | |
| 118 | try std.testing.expect(strncasecmp(@ptrCast("A"), @ptrCast("A"), 1) == 0); | |
| 119 | try std.testing.expect(strncasecmp(@ptrCast("B"), @ptrCast("b"), 1) == 0); | |
| 120 | try std.testing.expect(strncasecmp(@ptrCast("bb"), @ptrCast("AA"), 2) > 0); | |
| 121 | } |
lib/c/unistd.zig-26| ... | ... | @@ -206,32 +206,6 @@ fn swab(noalias src_ptr: *const anyopaque, noalias dest_ptr: *anyopaque, n: isiz |
| 206 | 206 | } |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | test swab { | |
| 210 | var a: [4]u8 = undefined; | |
| 211 | @memset(a[0..], '\x00'); | |
| 212 | swab("abcd", &a, 4); | |
| 213 | try std.testing.expectEqualSlices(u8, "badc", &a); | |
| 214 | ||
| 215 | // Partial copy | |
| 216 | @memset(a[0..], '\x00'); | |
| 217 | swab("abcd", &a, 2); | |
| 218 | try std.testing.expectEqualSlices(u8, "ba\x00\x00", &a); | |
| 219 | ||
| 220 | // n < 1 | |
| 221 | @memset(a[0..], '\x00'); | |
| 222 | swab("abcd", &a, 0); | |
| 223 | try std.testing.expectEqualSlices(u8, "\x00" ** 4, &a); | |
| 224 | swab("abcd", &a, -1); | |
| 225 | try std.testing.expectEqualSlices(u8, "\x00" ** 4, &a); | |
| 226 | ||
| 227 | // Odd n | |
| 228 | @memset(a[0..], '\x00'); | |
| 229 | swab("abcd", &a, 1); | |
| 230 | try std.testing.expectEqualSlices(u8, "\x00" ** 4, &a); | |
| 231 | swab("abcd", &a, 3); | |
| 232 | try std.testing.expectEqualSlices(u8, "ba\x00\x00", &a); | |
| 233 | } | |
| 234 | ||
| 235 | 209 | fn close(fd: std.c.fd_t) callconv(.c) c_int { |
| 236 | 210 | const signed: isize = @bitCast(linux.close(fd)); |
| 237 | 211 | if (signed < 0) { |
lib/std/c.zig+53-6| ... | ... | @@ -11102,13 +11102,60 @@ pub const ioctl = switch (native_os) { |
| 11102 | 11102 | else => private.ioctl, |
| 11103 | 11103 | }; |
| 11104 | 11104 | |
| 11105 | pub extern "c" fn bzero(s: *anyopaque, n: usize) void; | |
| 11106 | ||
| 11107 | pub extern "c" fn swab(noalias from: *const anyopaque, noalias to: *anyopaque, n: isize) void; | |
| 11108 | ||
| 11109 | pub extern "c" fn strncmp(a: [*:0]const c_char, b: [*:0]const c_char, max: usize) c_int; | |
| 11110 | pub extern "c" fn strcasecmp(a: [*:0]const c_char, b: [*:0]const c_char) c_int; | |
| 11111 | pub extern "c" fn strncasecmp(a: [*:0]const c_char, b: [*:0]const c_char, max: usize) c_int; | |
| 11112 | ||
| 11113 | pub extern "c" fn ffs(i: c_int) c_int; | |
| 11114 | pub extern "c" fn ffsl(i: c_long) c_long; | |
| 11115 | pub extern "c" fn ffsll(i: c_longlong) c_longlong; | |
| 11116 | ||
| 11117 | pub extern "c" fn erand48(xsubi: *[3]c_ushort) f64; | |
| 11118 | pub extern "c" fn jrand48(xsubi: *[3]c_ushort) c_long; | |
| 11119 | pub extern "c" fn nrand48(xsubi: *[3]c_ushort) c_long; | |
| 11120 | ||
| 11121 | pub extern "c" fn insque(element: *anyopaque, pred: ?*anyopaque) void; | |
| 11122 | pub extern "c" fn remque(element: *anyopaque) void; | |
| 11123 | ||
| 11124 | pub extern "c" fn imaxabs(a: intmax_t) intmax_t; | |
| 11125 | pub extern "c" fn imaxdiv(a: intmax_t, b: intmax_t) imaxdiv_t; | |
| 11126 | ||
| 11127 | pub extern "c" fn abs(a: c_int) c_int; | |
| 11128 | pub extern "c" fn labs(a: c_long) c_long; | |
| 11129 | pub extern "c" fn llabs(a: c_longlong) c_longlong; | |
| 11130 | ||
| 11131 | pub extern "c" fn div(a: c_int, b: c_int) div_t; | |
| 11132 | pub extern "c" fn ldiv(a: c_long, b: c_long) ldiv_t; | |
| 11133 | pub extern "c" fn lldiv(a: c_longlong, b: c_longlong) lldiv_t; | |
| 11134 | ||
| 11135 | pub extern "c" fn atoi(str: [*:0]const c_char) c_int; | |
| 11136 | pub extern "c" fn atol(str: [*:0]const c_char) c_long; | |
| 11137 | pub extern "c" fn atoll(str: [*:0]const c_char) c_longlong; | |
| 11138 | ||
| 11139 | pub extern "c" fn bsearch( | |
| 11140 | key: *const anyopaque, | |
| 11141 | base: *const anyopaque, | |
| 11142 | n: usize, | |
| 11143 | size: usize, | |
| 11144 | compare: *const fn (a: *const anyopaque, b: *const anyopaque) callconv(.c) c_int, | |
| 11145 | ) ?*anyopaque; | |
| 11146 | ||
| 11105 | 11147 | // Math |
| 11106 | pub extern "c" fn atan(x: f64) callconv(.c) f64; | |
| 11107 | pub extern "c" fn copysign(x: f64, y: f64) callconv(.c) f64; | |
| 11108 | pub extern "c" fn fdim(x: f64, y: f64) callconv(.c) f64; | |
| 11109 | pub extern "c" fn frexp(x: f64, e: *c_int) callconv(.c) f64; | |
| 11110 | pub extern "c" fn hypot(x: f64, y: f64) callconv(.c) f64; | |
| 11111 | pub extern "c" fn modf(x: f64, iptr: *f64) callconv(.c) f64; | |
| 11148 | pub extern "c" fn atan(x: f64) f64; | |
| 11149 | pub extern "c" fn copysign(x: f64, y: f64) f64; | |
| 11150 | pub extern "c" fn fdim(x: f64, y: f64) f64; | |
| 11151 | pub extern "c" fn frexp(x: f64, e: *c_int) f64; | |
| 11152 | pub extern "c" fn hypot(x: f64, y: f64) f64; | |
| 11153 | pub extern "c" fn modff(x: f32, iptr: *f32) f32; | |
| 11154 | pub extern "c" fn modf(x: f64, iptr: *f64) f64; | |
| 11155 | pub extern "c" fn modfl(x: c_longdouble, iptr: *c_longdouble) c_longdouble; | |
| 11156 | pub extern "c" fn rintf(x: f32) f32; | |
| 11157 | pub extern "c" fn rint(x: f64) f64; | |
| 11158 | pub extern "c" fn rintl(x: c_longdouble) c_longdouble; | |
| 11112 | 11159 | |
| 11113 | 11160 | // OS-specific bits. These are protected from being used on the wrong OS by |
| 11114 | 11161 | // comptime assertions inside each OS-specific file. |
lib/std/os.zig+41| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | const std = @import("std.zig"); | |
| 2 | 3 | const native_os = builtin.os.tag; |
| 3 | 4 | |
| 4 | 5 | pub const linux = @import("os/linux.zig"); |
| ... | ... | @@ -8,6 +9,46 @@ pub const wasi = @import("os/wasi.zig"); |
| 8 | 9 | pub const emscripten = @import("os/emscripten.zig"); |
| 9 | 10 | pub const windows = @import("os/windows.zig"); |
| 10 | 11 | |
| 12 | /// Returns whether the Zig standard library requires libc in order to interface | |
| 13 | /// with the operating system on the given target. | |
| 14 | pub fn targetRequiresLibC(target: *const std.Target) bool { | |
| 15 | if (target.requiresLibC()) return true; | |
| 16 | return switch (target.os.tag) { | |
| 17 | .linux => switch (target.cpu.arch) { | |
| 18 | // https://codeberg.org/ziglang/zig/issues/30940 | |
| 19 | .alpha, | |
| 20 | // https://codeberg.org/ziglang/zig/issues/30942 | |
| 21 | .csky, | |
| 22 | // https://codeberg.org/ziglang/zig/issues/30943 | |
| 23 | .hppa, | |
| 24 | .hppa64, | |
| 25 | // https://codeberg.org/ziglang/zig/issues/30944 | |
| 26 | .microblaze, | |
| 27 | .microblazeel, | |
| 28 | // https://codeberg.org/ziglang/zig/issues/30946 | |
| 29 | .sh, | |
| 30 | .sheb, | |
| 31 | // https://codeberg.org/ziglang/zig/issues/30945 | |
| 32 | .sparc, | |
| 33 | // https://codeberg.org/ziglang/zig/issues/30947 | |
| 34 | .xtensa, | |
| 35 | .xtensaeb, | |
| 36 | => true, | |
| 37 | else => false, | |
| 38 | }, | |
| 39 | .freebsd => true, // https://codeberg.org/ziglang/zig/issues/30981 | |
| 40 | .netbsd => true, // https://codeberg.org/ziglang/zig/issues/30980 | |
| 41 | .openbsd => true, // https://codeberg.org/ziglang/zig/issues/30982 | |
| 42 | else => false, | |
| 43 | }; | |
| 44 | } | |
| 45 | ||
| 46 | /// Returns whether the Zig standard library requires libc in order to interface | |
| 47 | /// with the operating system on the current target. | |
| 48 | pub fn requiresLibC() bool { | |
| 49 | return targetRequiresLibC(&builtin.target); | |
| 50 | } | |
| 51 | ||
| 11 | 52 | test { |
| 12 | 53 | _ = linux; |
| 13 | 54 | if (native_os == .uefi) _ = uefi; |
src/Compilation/Config.zig+1-10| ... | ... | @@ -234,19 +234,10 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 234 | 234 | break :b true; |
| 235 | 235 | } |
| 236 | 236 | if (options.link_libc) |x| break :b x; |
| 237 | switch (target.os.tag) { | |
| 238 | // These targets don't require libc, but we don't yet have a syscall layer for them, | |
| 239 | // so we default to linking libc for now. | |
| 240 | .freebsd, | |
| 241 | .netbsd, | |
| 242 | .openbsd, | |
| 243 | => break :b true, | |
| 244 | else => {}, | |
| 245 | } | |
| 246 | 237 | if (options.ensure_libc_on_non_freestanding and target.os.tag != .freestanding) |
| 247 | 238 | break :b true; |
| 248 | 239 | |
| 249 | break :b target.requiresLibC(); | |
| 240 | break :b std.os.targetRequiresLibC(target); | |
| 250 | 241 | }; |
| 251 | 242 | |
| 252 | 243 | const link_mode = b: { |
test/c.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | test { | |
| 5 | _ = @import("c/inttypes.zig"); | |
| 6 | _ = @import("c/math.zig"); | |
| 7 | _ = @import("c/search.zig"); | |
| 8 | _ = @import("c/stdlib.zig"); | |
| 9 | _ = @import("c/string.zig"); | |
| 10 | _ = @import("c/strings.zig"); | |
| 11 | _ = @import("c/unistd.zig"); | |
| 12 | } |
test/c/inttypes.zig created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | const c = std.c; | |
| 5 | const testing = std.testing; | |
| 6 | ||
| 7 | test "imaxabs" { | |
| 8 | const val: c.intmax_t = -10; | |
| 9 | try testing.expectEqual(10, c.imaxabs(val)); | |
| 10 | } | |
| 11 | ||
| 12 | test "imaxdiv" { | |
| 13 | if (builtin.target.cpu.arch.isPowerPC32()) return error.SkipZigTest; // TODO | |
| 14 | if (builtin.target.cpu.arch == .s390x) return error.SkipZigTest; // TODO | |
| 15 | ||
| 16 | const expected: c.imaxdiv_t = .{ .quot = 9, .rem = 0 }; | |
| 17 | try testing.expectEqual(expected, c.imaxdiv(9, 1)); | |
| 18 | } |
test/c/math.zig created+104| ... | ... | @@ -0,0 +1,104 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | const c = std.c; | |
| 5 | const math = std.math; | |
| 6 | const testing = std.testing; | |
| 7 | ||
| 8 | fn testModf(comptime T: type) !void { | |
| 9 | const f = switch (T) { | |
| 10 | f32 => c.modff, | |
| 11 | f64 => c.modf, | |
| 12 | c_longdouble => c.modfl, | |
| 13 | else => unreachable, | |
| 14 | }; | |
| 15 | ||
| 16 | var int: T = undefined; | |
| 17 | const iptr = &int; | |
| 18 | const eps_val: comptime_float = @max(1e-6, math.floatEps(T)); | |
| 19 | ||
| 20 | const normal_frac = f(@as(T, 1234.567), iptr); | |
| 21 | // Account for precision error | |
| 22 | const expected = 1234.567 - @as(T, 1234); | |
| 23 | try testing.expectApproxEqAbs(expected, normal_frac, eps_val); | |
| 24 | try testing.expectApproxEqRel(@as(T, 1234.0), iptr.*, eps_val); | |
| 25 | ||
| 26 | // When `x` is a NaN, NaN is returned and `*iptr` is set to NaN | |
| 27 | const nan_frac = f(math.nan(T), iptr); | |
| 28 | try testing.expect(math.isNan(nan_frac)); | |
| 29 | try testing.expect(math.isNan(iptr.*)); | |
| 30 | ||
| 31 | // When `x` is positive infinity, +0 is returned and `*iptr` is set to | |
| 32 | // positive infinity | |
| 33 | const pos_zero_frac = f(math.inf(T), iptr); | |
| 34 | try testing.expect(math.isPositiveZero(pos_zero_frac)); | |
| 35 | try testing.expect(math.isPositiveInf(iptr.*)); | |
| 36 | ||
| 37 | // When `x` is negative infinity, -0 is returned and `*iptr` is set to | |
| 38 | // negative infinity | |
| 39 | const neg_zero_frac = f(-math.inf(T), iptr); | |
| 40 | try testing.expect(math.isNegativeZero(neg_zero_frac)); | |
| 41 | try testing.expect(math.isNegativeInf(iptr.*)); | |
| 42 | ||
| 43 | // Return -0 when `x` is a negative integer | |
| 44 | const nz_frac = f(@as(T, -1000.0), iptr); | |
| 45 | try testing.expect(math.isNegativeZero(nz_frac)); | |
| 46 | try testing.expectEqual(@as(T, -1000.0), iptr.*); | |
| 47 | ||
| 48 | // Return +0 when `x` is a positive integer | |
| 49 | const pz_frac = f(@as(T, 1000.0), iptr); | |
| 50 | try testing.expect(math.isPositiveZero(pz_frac)); | |
| 51 | try testing.expectEqual(@as(T, 1000.0), iptr.*); | |
| 52 | } | |
| 53 | ||
| 54 | test "modf" { | |
| 55 | try testModf(f32); | |
| 56 | try testModf(f64); | |
| 57 | ||
| 58 | if (builtin.target.cpu.arch.isPowerPC()) return error.SkipZigTest; // TODO | |
| 59 | ||
| 60 | try testModf(c_longdouble); | |
| 61 | } | |
| 62 | ||
| 63 | fn testRint(comptime T: type) !void { | |
| 64 | const f = switch (T) { | |
| 65 | f32 => c.rintf, | |
| 66 | f64 => c.rint, | |
| 67 | else => @compileError("rint not implemented for" ++ @typeName(T)), | |
| 68 | }; | |
| 69 | ||
| 70 | // Positive numbers round correctly | |
| 71 | try testing.expectEqual(@as(T, 42.0), f(42.2)); | |
| 72 | try testing.expectEqual(@as(T, 42.0), f(41.8)); | |
| 73 | ||
| 74 | // Negative numbers round correctly | |
| 75 | try testing.expectEqual(@as(T, -6.0), f(-5.9)); | |
| 76 | try testing.expectEqual(@as(T, -6.0), f(-6.1)); | |
| 77 | ||
| 78 | // No rounding needed test | |
| 79 | try testing.expectEqual(@as(T, 5.0), f(5.0)); | |
| 80 | try testing.expectEqual(@as(T, -10.0), f(-10.0)); | |
| 81 | try testing.expectEqual(@as(T, 0.0), f(0.0)); | |
| 82 | ||
| 83 | // Very large numbers return unchanged | |
| 84 | const large: T = 9007199254740992.0; // 2^53 | |
| 85 | try testing.expectEqual(large, f(large)); | |
| 86 | try testing.expectEqual(-large, f(-large)); | |
| 87 | ||
| 88 | // Small positive numbers round to zero | |
| 89 | const pos_result = f(0.3); | |
| 90 | try testing.expect(math.isPositiveZero(pos_result)); | |
| 91 | ||
| 92 | // Small negative numbers round to negative zero | |
| 93 | const neg_result = f(-0.3); | |
| 94 | try testing.expect(math.isNegativeZero(neg_result)); | |
| 95 | ||
| 96 | // Exact half rounds to nearest even (banker's rounding) | |
| 97 | try testing.expectEqual(@as(T, 2.0), f(2.5)); | |
| 98 | try testing.expectEqual(@as(T, 4.0), f(3.5)); | |
| 99 | } | |
| 100 | ||
| 101 | test "rint" { | |
| 102 | try testRint(f32); | |
| 103 | try testRint(f64); | |
| 104 | } |
test/c/search.zig created+40| ... | ... | @@ -0,0 +1,40 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | const c = std.c; | |
| 5 | const testing = std.testing; | |
| 6 | ||
| 7 | /// Not defined in `std.c` because C headers don't either. | |
| 8 | const Node = extern struct { | |
| 9 | next: ?*Node, | |
| 10 | prev: ?*Node, | |
| 11 | }; | |
| 12 | ||
| 13 | test "insque and remque" { | |
| 14 | if (builtin.target.os.tag == .windows) return; // no insque/remque | |
| 15 | ||
| 16 | var first: Node = .{ .next = null, .prev = null }; | |
| 17 | var second: Node = .{ .next = null, .prev = null }; | |
| 18 | var third: Node = .{ .next = null, .prev = null }; | |
| 19 | ||
| 20 | c.insque(&first, null); | |
| 21 | try testing.expectEqual(@as(?*Node, null), first.next); | |
| 22 | try testing.expectEqual(@as(?*Node, null), first.prev); | |
| 23 | ||
| 24 | c.insque(&second, &first); | |
| 25 | try testing.expectEqual(@as(?*Node, &second), first.next); | |
| 26 | try testing.expectEqual(@as(?*Node, &first), second.prev); | |
| 27 | ||
| 28 | c.insque(&third, &first); | |
| 29 | try testing.expectEqual(@as(?*Node, &third), first.next); | |
| 30 | try testing.expectEqual(@as(?*Node, &second), third.next); | |
| 31 | try testing.expectEqual(@as(?*Node, &first), third.prev); | |
| 32 | try testing.expectEqual(@as(?*Node, &third), second.prev); | |
| 33 | ||
| 34 | c.remque(&third); | |
| 35 | try testing.expectEqual(@as(?*Node, &second), first.next); | |
| 36 | try testing.expectEqual(@as(?*Node, &first), second.prev); | |
| 37 | ||
| 38 | c.remque(&second); | |
| 39 | try testing.expectEqual(@as(?*Node, null), first.next); | |
| 40 | } |
test/c/stdlib.zig created+125| ... | ... | @@ -0,0 +1,125 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | const c = std.c; | |
| 5 | const fmt = std.fmt; | |
| 6 | const math = std.math; | |
| 7 | const testing = std.testing; | |
| 8 | ||
| 9 | test "abs" { | |
| 10 | if (builtin.target.cpu.arch.isMIPS64()) return error.SkipZigTest; // TODO | |
| 11 | ||
| 12 | const val: c_int = -10; | |
| 13 | try testing.expectEqual(10, c.abs(val)); | |
| 14 | } | |
| 15 | ||
| 16 | test "labs" { | |
| 17 | if (builtin.target.cpu.arch.isMIPS64() and @sizeOf(usize) == 4) return error.SkipZigTest; // TODO | |
| 18 | ||
| 19 | const val: c_long = -10; | |
| 20 | try testing.expectEqual(10, c.labs(val)); | |
| 21 | } | |
| 22 | ||
| 23 | test "llabs" { | |
| 24 | const val: c_longlong = -10; | |
| 25 | try testing.expectEqual(10, c.llabs(val)); | |
| 26 | } | |
| 27 | ||
| 28 | test "div" { | |
| 29 | if (builtin.target.cpu.arch.isLoongArch()) return error.SkipZigTest; // TODO | |
| 30 | if (builtin.target.cpu.arch.isMIPS64()) return error.SkipZigTest; // TODO | |
| 31 | if (builtin.target.cpu.arch.isPowerPC()) return error.SkipZigTest; // TODO | |
| 32 | if (builtin.target.cpu.arch == .s390x) return error.SkipZigTest; // TODO | |
| 33 | ||
| 34 | const expected: c.div_t = .{ .quot = 5, .rem = 5 }; | |
| 35 | try testing.expectEqual(expected, c.div(55, 10)); | |
| 36 | } | |
| 37 | ||
| 38 | test "ldiv" { | |
| 39 | if (builtin.target.cpu.arch.isMIPS64() and @sizeOf(usize) == 4) return error.SkipZigTest; // TODO | |
| 40 | if (builtin.target.cpu.arch.isPowerPC32()) return error.SkipZigTest; // TODO | |
| 41 | if (builtin.target.cpu.arch == .s390x) return error.SkipZigTest; // TODO | |
| 42 | ||
| 43 | const expected: c.ldiv_t = .{ .quot = -6, .rem = 2 }; | |
| 44 | try testing.expectEqual(expected, c.ldiv(38, -6)); | |
| 45 | } | |
| 46 | ||
| 47 | test "lldiv" { | |
| 48 | if (builtin.target.cpu.arch.isPowerPC32()) return error.SkipZigTest; // TODO | |
| 49 | if (builtin.target.cpu.arch == .s390x) return error.SkipZigTest; // TODO | |
| 50 | ||
| 51 | const expected: c.lldiv_t = .{ .quot = 1, .rem = 2 }; | |
| 52 | try testing.expectEqual(expected, c.lldiv(5, 3)); | |
| 53 | } | |
| 54 | ||
| 55 | test "atoi" { | |
| 56 | try testing.expectEqual(0, c.atoi(@ptrCast("stop42true"))); | |
| 57 | try testing.expectEqual(42, c.atoi(@ptrCast("42true"))); | |
| 58 | try testing.expectEqual(-1, c.atoi(@ptrCast("-01"))); | |
| 59 | try testing.expectEqual(1, c.atoi(@ptrCast("+001"))); | |
| 60 | try testing.expectEqual(100, c.atoi(@ptrCast(" 100"))); | |
| 61 | try testing.expectEqual(500, c.atoi(@ptrCast("000000000000500"))); | |
| 62 | try testing.expectEqual(1111, c.atoi(@ptrCast("0000000000001111_0000"))); | |
| 63 | try testing.expectEqual(0, c.atoi(@ptrCast("0xAA"))); | |
| 64 | try testing.expectEqual(700, c.atoi(@ptrCast("700B"))); | |
| 65 | try testing.expectEqual(32453, c.atoi(@ptrCast("+32453more"))); | |
| 66 | try testing.expectEqual(math.maxInt(c_int), c.atoi(@ptrCast(fmt.comptimePrint("{d}", .{math.maxInt(c_int)})))); | |
| 67 | try testing.expectEqual(math.minInt(c_int), c.atoi(@ptrCast(fmt.comptimePrint("{d}", .{math.minInt(c_int)})))); | |
| 68 | } | |
| 69 | ||
| 70 | test "atol" { | |
| 71 | try testing.expectEqual(0, c.atol(@ptrCast("stop42true"))); | |
| 72 | try testing.expectEqual(42, c.atol(@ptrCast("42true"))); | |
| 73 | try testing.expectEqual(-1, c.atol(@ptrCast("-01"))); | |
| 74 | try testing.expectEqual(1, c.atol(@ptrCast("+001"))); | |
| 75 | try testing.expectEqual(100, c.atol(@ptrCast(" 100"))); | |
| 76 | try testing.expectEqual(500, c.atol(@ptrCast("000000000000500"))); | |
| 77 | try testing.expectEqual(1111, c.atol(@ptrCast("0000000000001111_0000"))); | |
| 78 | try testing.expectEqual(0, c.atol(@ptrCast("0xAA"))); | |
| 79 | try testing.expectEqual(700, c.atol(@ptrCast("700B"))); | |
| 80 | try testing.expectEqual(32453, c.atol(@ptrCast("+32453more"))); | |
| 81 | try testing.expectEqual(math.maxInt(c_long), c.atol(@ptrCast(fmt.comptimePrint("{d}", .{math.maxInt(c_long)})))); | |
| 82 | try testing.expectEqual(math.minInt(c_long), c.atol(@ptrCast(fmt.comptimePrint("{d}", .{math.minInt(c_long)})))); | |
| 83 | } | |
| 84 | ||
| 85 | test "atoll" { | |
| 86 | try testing.expectEqual(0, c.atoll(@ptrCast("stop42true"))); | |
| 87 | try testing.expectEqual(42, c.atoll(@ptrCast("42true"))); | |
| 88 | try testing.expectEqual(-1, c.atoll(@ptrCast("-01"))); | |
| 89 | try testing.expectEqual(1, c.atoll(@ptrCast("+001"))); | |
| 90 | try testing.expectEqual(100, c.atoll(@ptrCast(" 100"))); | |
| 91 | try testing.expectEqual(500, c.atoll(@ptrCast("000000000000500"))); | |
| 92 | try testing.expectEqual(1111, c.atoll(@ptrCast("0000000000001111_0000"))); | |
| 93 | try testing.expectEqual(0, c.atoll(@ptrCast("0xAA"))); | |
| 94 | try testing.expectEqual(700, c.atoll(@ptrCast("700B"))); | |
| 95 | try testing.expectEqual(32453, c.atoll(@ptrCast(" +32453more"))); | |
| 96 | try testing.expectEqual(math.maxInt(c_longlong), c.atoll(@ptrCast(fmt.comptimePrint("{d}", .{math.maxInt(c_longlong)})))); | |
| 97 | try testing.expectEqual(math.minInt(c_longlong), c.atoll(@ptrCast(fmt.comptimePrint("{d}", .{math.minInt(c_longlong)})))); | |
| 98 | } | |
| 99 | ||
| 100 | test "bsearch" { | |
| 101 | const Comparison = struct { | |
| 102 | pub fn compare(a: *const anyopaque, b: *const anyopaque) callconv(.c) c_int { | |
| 103 | const a_u16: *const u16 = @ptrCast(@alignCast(a)); | |
| 104 | const b_u16: *const u16 = @ptrCast(@alignCast(b)); | |
| 105 | ||
| 106 | return switch (math.order(a_u16.*, b_u16.*)) { | |
| 107 | .gt => 1, | |
| 108 | .eq => 0, | |
| 109 | .lt => -1, | |
| 110 | }; | |
| 111 | } | |
| 112 | }; | |
| 113 | ||
| 114 | const items: []const u16 = &.{ 0, 5, 7, 9, 10, 200, 512, 768 }; | |
| 115 | ||
| 116 | try testing.expectEqual(@as(?*anyopaque, null), c.bsearch(&@as(u16, 2000), items.ptr, items.len, @sizeOf(u16), Comparison.compare)); | |
| 117 | ||
| 118 | for (items) |*value| { | |
| 119 | try testing.expectEqual(@as(*const anyopaque, value), c.bsearch(value, items.ptr, items.len, @sizeOf(u16), Comparison.compare)); | |
| 120 | } | |
| 121 | } | |
| 122 | ||
| 123 | test { | |
| 124 | _ = @import("stdlib/drand48.zig"); | |
| 125 | } |
test/c/stdlib/drand48.zig created+70| ... | ... | @@ -0,0 +1,70 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | const c = std.c; | |
| 5 | const testing = std.testing; | |
| 6 | ||
| 7 | test "erand48" { | |
| 8 | if (builtin.target.os.tag == .windows) return; // no erand48 | |
| 9 | ||
| 10 | var xsubi: [3]c_ushort = .{ 37174, 64810, 11603 }; | |
| 11 | ||
| 12 | try testing.expectApproxEqAbs(0.8965, c.erand48(&xsubi), 0.0005); | |
| 13 | try testing.expectEqualSlices(c_ushort, &.{ 22537, 47966, 58735 }, &xsubi); | |
| 14 | ||
| 15 | try testing.expectApproxEqAbs(0.3375, c.erand48(&xsubi), 0.0005); | |
| 16 | try testing.expectEqualSlices(c_ushort, &.{ 37344, 32911, 22119 }, &xsubi); | |
| 17 | ||
| 18 | try testing.expectApproxEqAbs(0.6475, c.erand48(&xsubi), 0.0005); | |
| 19 | try testing.expectEqualSlices(c_ushort, &.{ 23659, 29872, 42445 }, &xsubi); | |
| 20 | ||
| 21 | try testing.expectApproxEqAbs(0.5005, c.erand48(&xsubi), 0.0005); | |
| 22 | try testing.expectEqualSlices(c_ushort, &.{ 31642, 7875, 32802 }, &xsubi); | |
| 23 | ||
| 24 | try testing.expectApproxEqAbs(0.5065, c.erand48(&xsubi), 0.0005); | |
| 25 | try testing.expectEqualSlices(c_ushort, &.{ 64669, 14399, 33170 }, &xsubi); | |
| 26 | } | |
| 27 | ||
| 28 | test "jrand48" { | |
| 29 | if (builtin.target.os.tag == .windows) return; // no jrand48 | |
| 30 | ||
| 31 | if (builtin.target.os.tag == .openbsd) return error.SkipZigTest; // TODO | |
| 32 | ||
| 33 | var xsubi: [3]c_ushort = .{ 25175, 11052, 45015 }; | |
| 34 | ||
| 35 | try testing.expectEqual(1699503220, c.jrand48(&xsubi)); | |
| 36 | try testing.expectEqualSlices(c_ushort, &.{ 2326, 23668, 25932 }, &xsubi); | |
| 37 | ||
| 38 | try testing.expectEqual(-992276007, c.jrand48(&xsubi)); | |
| 39 | try testing.expectEqualSlices(c_ushort, &.{ 41577, 4569, 50395 }, &xsubi); | |
| 40 | ||
| 41 | try testing.expectEqual(-19535776, c.jrand48(&xsubi)); | |
| 42 | try testing.expectEqualSlices(c_ushort, &.{ 31936, 59488, 65237 }, &xsubi); | |
| 43 | ||
| 44 | try testing.expectEqual(79438377, c.jrand48(&xsubi)); | |
| 45 | try testing.expectEqualSlices(c_ushort, &.{ 40395, 8745, 1212 }, &xsubi); | |
| 46 | ||
| 47 | try testing.expectEqual(-1258917728, c.jrand48(&xsubi)); | |
| 48 | try testing.expectEqualSlices(c_ushort, &.{ 37242, 28832, 46326 }, &xsubi); | |
| 49 | } | |
| 50 | ||
| 51 | test "nrand48" { | |
| 52 | if (builtin.target.os.tag == .windows) return; // no nrand48 | |
| 53 | ||
| 54 | var xsubi: [3]c_ushort = .{ 546, 33817, 23389 }; | |
| 55 | ||
| 56 | try testing.expectEqual(914920692, c.nrand48(&xsubi)); | |
| 57 | try testing.expectEqualSlices(c_ushort, &.{ 29829, 10728, 27921 }, &xsubi); | |
| 58 | ||
| 59 | try testing.expectEqual(754104482, c.nrand48(&xsubi)); | |
| 60 | try testing.expectEqualSlices(c_ushort, &.{ 6828, 28997, 23013 }, &xsubi); | |
| 61 | ||
| 62 | try testing.expectEqual(609453945, c.nrand48(&xsubi)); | |
| 63 | try testing.expectEqualSlices(c_ushort, &.{ 58183, 3826, 18599 }, &xsubi); | |
| 64 | ||
| 65 | try testing.expectEqual(1878644360, c.nrand48(&xsubi)); | |
| 66 | try testing.expectEqualSlices(c_ushort, &.{ 36678, 44304, 57331 }, &xsubi); | |
| 67 | ||
| 68 | try testing.expectEqual(2114923686, c.nrand48(&xsubi)); | |
| 69 | try testing.expectEqualSlices(c_ushort, &.{ 58585, 22861, 64542 }, &xsubi); | |
| 70 | } |
test/c/string.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | const c = std.c; | |
| 5 | const testing = std.testing; | |
| 6 | ||
| 7 | test "strncmp" { | |
| 8 | try testing.expect(c.strncmp(@ptrCast("a"), @ptrCast("b"), 1) < 0); | |
| 9 | try testing.expect(c.strncmp(@ptrCast("a"), @ptrCast("c"), 1) < 0); | |
| 10 | try testing.expect(c.strncmp(@ptrCast("b"), @ptrCast("a"), 1) > 0); | |
| 11 | try testing.expect(c.strncmp(@ptrCast("\xff"), @ptrCast("\x02"), 1) > 0); | |
| 12 | } |
test/c/strings.zig created+68| ... | ... | @@ -0,0 +1,68 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | const c = std.c; | |
| 5 | const mem = std.mem; | |
| 6 | const testing = std.testing; | |
| 7 | ||
| 8 | test "bzero" { | |
| 9 | if (builtin.target.os.tag == .windows) return; // no bzero | |
| 10 | ||
| 11 | var array: [10]u8 = [_]u8{ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' }; | |
| 12 | var a = mem.zeroes([array.len]u8); | |
| 13 | a[9] = '0'; | |
| 14 | c.bzero(&array[0], 9); | |
| 15 | try testing.expect(mem.eql(u8, &array, &a)); | |
| 16 | } | |
| 17 | ||
| 18 | fn testFfs(comptime T: type) !void { | |
| 19 | const ffs = switch (T) { | |
| 20 | c_int => c.ffs, | |
| 21 | c_long => c.ffsl, | |
| 22 | c_longlong => c.ffsll, | |
| 23 | else => unreachable, | |
| 24 | }; | |
| 25 | ||
| 26 | try testing.expectEqual(0, ffs(0)); | |
| 27 | ||
| 28 | for (0..@bitSizeOf(T)) |i| { | |
| 29 | const bit = @as(T, 1) << @intCast(i); | |
| 30 | ||
| 31 | try testing.expectEqual(@as(T, @intCast(i + 1)), ffs(bit)); | |
| 32 | } | |
| 33 | } | |
| 34 | ||
| 35 | test "ffs" { | |
| 36 | if (builtin.target.os.tag == .openbsd) return; // no ffsl/ffsll | |
| 37 | if (builtin.target.os.tag == .windows) return; // no ffs | |
| 38 | ||
| 39 | try testFfs(c_int); | |
| 40 | ||
| 41 | if (builtin.target.os.tag == .netbsd) return; // no ffsl/ffsll until 11 | |
| 42 | ||
| 43 | try testFfs(c_long); | |
| 44 | ||
| 45 | if (@sizeOf(usize) == 4) return error.SkipZigTest; // TODO | |
| 46 | ||
| 47 | try testFfs(c_longlong); | |
| 48 | } | |
| 49 | ||
| 50 | test "strcasecmp" { | |
| 51 | try testing.expect(c.strcasecmp(@ptrCast("a"), @ptrCast("b")) < 0); | |
| 52 | try testing.expect(c.strcasecmp(@ptrCast("b"), @ptrCast("a")) > 0); | |
| 53 | try testing.expect(c.strcasecmp(@ptrCast("A"), @ptrCast("b")) < 0); | |
| 54 | try testing.expect(c.strcasecmp(@ptrCast("b"), @ptrCast("A")) > 0); | |
| 55 | try testing.expect(c.strcasecmp(@ptrCast("A"), @ptrCast("A")) == 0); | |
| 56 | try testing.expect(c.strcasecmp(@ptrCast("B"), @ptrCast("b")) == 0); | |
| 57 | try testing.expect(c.strcasecmp(@ptrCast("bb"), @ptrCast("AA")) > 0); | |
| 58 | } | |
| 59 | ||
| 60 | test "strncasecmp" { | |
| 61 | try testing.expect(c.strncasecmp(@ptrCast("a"), @ptrCast("b"), 1) < 0); | |
| 62 | try testing.expect(c.strncasecmp(@ptrCast("b"), @ptrCast("a"), 1) > 0); | |
| 63 | try testing.expect(c.strncasecmp(@ptrCast("A"), @ptrCast("b"), 1) < 0); | |
| 64 | try testing.expect(c.strncasecmp(@ptrCast("b"), @ptrCast("A"), 1) > 0); | |
| 65 | try testing.expect(c.strncasecmp(@ptrCast("A"), @ptrCast("A"), 1) == 0); | |
| 66 | try testing.expect(c.strncasecmp(@ptrCast("B"), @ptrCast("b"), 1) == 0); | |
| 67 | try testing.expect(c.strncasecmp(@ptrCast("bb"), @ptrCast("AA"), 2) > 0); | |
| 68 | } |
test/c/unistd.zig created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | const c = std.c; | |
| 5 | const testing = std.testing; | |
| 6 | ||
| 7 | test "swab" { | |
| 8 | if (builtin.target.cpu.arch.isMIPS64() and @sizeOf(usize) == 4) return error.SkipZigTest; // TODO | |
| 9 | if (builtin.target.cpu.arch == .x86_64 and @sizeOf(usize) == 4) return error.SkipZigTest; // TODO | |
| 10 | if (builtin.target.os.tag == .netbsd) return error.SkipZigTest; // TODO | |
| 11 | ||
| 12 | var a: [4]u8 = undefined; | |
| 13 | @memset(a[0..], '\x00'); | |
| 14 | c.swab("abcd", &a, 4); | |
| 15 | try testing.expectEqualSlices(u8, "badc", &a); | |
| 16 | ||
| 17 | // Partial copy | |
| 18 | @memset(a[0..], '\x00'); | |
| 19 | c.swab("abcd", &a, 2); | |
| 20 | try testing.expectEqualSlices(u8, "ba\x00\x00", &a); | |
| 21 | ||
| 22 | // n < 1 | |
| 23 | @memset(a[0..], '\x00'); | |
| 24 | c.swab("abcd", &a, 0); | |
| 25 | try testing.expectEqualSlices(u8, "\x00" ** 4, &a); | |
| 26 | c.swab("abcd", &a, -1); | |
| 27 | try testing.expectEqualSlices(u8, "\x00" ** 4, &a); | |
| 28 | ||
| 29 | // Odd n | |
| 30 | @memset(a[0..], '\x00'); | |
| 31 | c.swab("abcd", &a, 1); | |
| 32 | try testing.expectEqualSlices(u8, "\x00" ** 4, &a); | |
| 33 | c.swab("abcd", &a, 3); | |
| 34 | try testing.expectEqualSlices(u8, "ba\x00\x00", &a); | |
| 35 | } |
test/src/StackTrace.zig+1-4| ... | ... | @@ -58,10 +58,7 @@ fn addCaseTarget( |
| 58 | 58 | .fuchsia => false, |
| 59 | 59 | else => true, |
| 60 | 60 | }; |
| 61 | const both_libc = switch (target.result.os.tag) { | |
| 62 | .freebsd, .netbsd, .openbsd => false, | |
| 63 | else => !target.result.requiresLibC(), | |
| 64 | }; | |
| 61 | const both_libc = !std.os.targetRequiresLibC(&target.result); | |
| 65 | 62 | |
| 66 | 63 | // See `std.debug.StackIterator.fp_usability` logic. |
| 67 | 64 | const fp_usability: enum { useless, unsafe, safe, ideal } = switch (target.result.cpu.arch) { |
test/tests.zig+23-42| ... | ... | @@ -18,7 +18,7 @@ pub const DebuggerContext = @import("src/Debugger.zig"); |
| 18 | 18 | pub const LlvmIrContext = @import("src/LlvmIr.zig"); |
| 19 | 19 | pub const LibcContext = @import("src/Libc.zig"); |
| 20 | 20 | |
| 21 | const TestTarget = struct { | |
| 21 | const ModuleTestTarget = struct { | |
| 22 | 22 | linkage: ?std.builtin.LinkMode = null, |
| 23 | 23 | target: std.Target.Query = .{}, |
| 24 | 24 | optimize_mode: std.builtin.OptimizeMode = .Debug, |
| ... | ... | @@ -36,33 +36,14 @@ const TestTarget = struct { |
| 36 | 36 | // invocation. This could be because of a slow backend, requiring a newer LLVM version, being |
| 37 | 37 | // too niche, etc. |
| 38 | 38 | extra_target: bool = false, |
| 39 | ||
| 40 | pub fn supportsModule( | |
| 41 | self: *const TestTarget, | |
| 42 | target: *const std.Build.ResolvedTarget, | |
| 43 | name: []const u8, | |
| 44 | ) bool { | |
| 45 | if (mem.eql(u8, name, "zigc")) { | |
| 46 | if (target.result.isMuslLibC()) return self.linkage == .static or (self.linkage == null and !target.query.isNative()); | |
| 47 | if (target.result.isMinGW()) return true; | |
| 48 | if (target.result.isWasiLibC()) return true; | |
| 49 | return false; | |
| 50 | } | |
| 51 | if (mem.eql(u8, name, "std")) { | |
| 52 | if (target.result.cpu.arch.isSpirV()) return false; | |
| 53 | return true; | |
| 54 | } | |
| 55 | ||
| 56 | return true; | |
| 57 | } | |
| 58 | 39 | }; |
| 59 | 40 | |
| 60 | const test_targets = blk: { | |
| 41 | const module_test_targets = blk: { | |
| 61 | 42 | // getBaselineCpuFeatures calls populateDependencies which has a O(N ^ 2) algorithm |
| 62 | 43 | // (where N is roughly 160, which technically makes it O(1), but it adds up to a |
| 63 | 44 | // lot of branches) |
| 64 | 45 | @setEvalBranchQuota(80_000); |
| 65 | break :blk [_]TestTarget{ | |
| 46 | break :blk [_]ModuleTestTarget{ | |
| 66 | 47 | // Native Targets |
| 67 | 48 | |
| 68 | 49 | .{}, // 0 index must be all defaults |
| ... | ... | @@ -2475,24 +2456,21 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 2475 | 2456 | const step = b.step(b.fmt("test-{s}", .{options.name}), options.desc); |
| 2476 | 2457 | |
| 2477 | 2458 | if (options.test_only) |test_only| { |
| 2478 | const test_target: TestTarget = switch (test_only) { | |
| 2479 | .default => test_targets[0], | |
| 2459 | const test_target: ModuleTestTarget = switch (test_only) { | |
| 2460 | .default => module_test_targets[0], | |
| 2480 | 2461 | .fuzz => |optimize| .{ |
| 2481 | 2462 | .optimize_mode = optimize, |
| 2482 | 2463 | .use_llvm = true, |
| 2483 | 2464 | }, |
| 2484 | 2465 | }; |
| 2485 | 2466 | const resolved_target = b.resolveTargetQuery(test_target.target); |
| 2486 | ||
| 2487 | if (test_target.supportsModule(&resolved_target, options.name)) { | |
| 2488 | const triple_txt = resolved_target.query.zigTriple(b.allocator) catch @panic("OOM"); | |
| 2489 | addOneModuleTest(b, step, test_target, &resolved_target, triple_txt, options); | |
| 2490 | } | |
| 2467 | const triple_txt = resolved_target.query.zigTriple(b.allocator) catch @panic("OOM"); | |
| 2468 | addOneModuleTest(b, step, test_target, &resolved_target, triple_txt, options); | |
| 2491 | 2469 | |
| 2492 | 2470 | return step; |
| 2493 | 2471 | } |
| 2494 | 2472 | |
| 2495 | for_targets: for (test_targets) |test_target| { | |
| 2473 | for_targets: for (module_test_targets) |test_target| { | |
| 2496 | 2474 | if (test_target.skip_modules.len > 0) { |
| 2497 | 2475 | for (test_target.skip_modules) |skip_mod| { |
| 2498 | 2476 | if (std.mem.eql(u8, options.name, skip_mod)) continue :for_targets; |
| ... | ... | @@ -2501,8 +2479,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 2501 | 2479 | |
| 2502 | 2480 | const resolved_target = b.resolveTargetQuery(test_target.target); |
| 2503 | 2481 | |
| 2504 | if (!test_target.supportsModule(&resolved_target, options.name)) continue; | |
| 2505 | ||
| 2506 | 2482 | if (!options.test_extra_targets and test_target.extra_target) continue; |
| 2507 | 2483 | |
| 2508 | 2484 | if (options.skip_non_native and !test_target.target.isNative()) |
| ... | ... | @@ -2510,6 +2486,13 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 2510 | 2486 | |
| 2511 | 2487 | const target = &resolved_target.result; |
| 2512 | 2488 | |
| 2489 | if (std.mem.eql(u8, options.name, "libc")) { | |
| 2490 | // The libc API tests obviously need to link libc. So for test | |
| 2491 | // target entries where we wouldn't link libc by default, skip the | |
| 2492 | // libc API tests. | |
| 2493 | if (test_target.link_libc == null and !std.os.targetRequiresLibC(target)) continue; | |
| 2494 | } | |
| 2495 | ||
| 2513 | 2496 | if (options.skip_spirv and target.cpu.arch.isSpirV()) continue; |
| 2514 | 2497 | if (options.skip_wasm and target.cpu.arch.isWasm()) continue; |
| 2515 | 2498 | |
| ... | ... | @@ -2531,7 +2514,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 2531 | 2514 | } else continue; |
| 2532 | 2515 | } |
| 2533 | 2516 | |
| 2534 | if (options.skip_libc and test_target.link_libc == true) | |
| 2517 | if (options.skip_libc and (test_target.link_libc == true or std.os.targetRequiresLibC(target))) | |
| 2535 | 2518 | continue; |
| 2536 | 2519 | |
| 2537 | 2520 | // We can't provide MSVC libc when cross-compiling. |
| ... | ... | @@ -2544,8 +2527,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 2544 | 2527 | if (!would_use_llvm and target.cpu.arch == .aarch64) { |
| 2545 | 2528 | // TODO get std tests passing for the aarch64 self-hosted backend. |
| 2546 | 2529 | if (mem.eql(u8, options.name, "std")) continue; |
| 2547 | // TODO get zigc tests passing for the aarch64 self-hosted backend. | |
| 2548 | if (mem.eql(u8, options.name, "zigc")) continue; | |
| 2549 | 2530 | } |
| 2550 | 2531 | |
| 2551 | 2532 | const want_this_mode = for (options.optimize_modes) |m| { |
| ... | ... | @@ -2561,7 +2542,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 2561 | 2542 | fn addOneModuleTest( |
| 2562 | 2543 | b: *std.Build, |
| 2563 | 2544 | step: *Step, |
| 2564 | test_target: TestTarget, | |
| 2545 | test_target: ModuleTestTarget, | |
| 2565 | 2546 | resolved_target: *const std.Build.ResolvedTarget, |
| 2566 | 2547 | triple_txt: []const u8, |
| 2567 | 2548 | options: ModuleTestOptions, |
| ... | ... | @@ -2598,11 +2579,11 @@ fn addOneModuleTest( |
| 2598 | 2579 | }); |
| 2599 | 2580 | these_tests.linkage = test_target.linkage; |
| 2600 | 2581 | // https://codeberg.org/ziglang/zig/issues/31701 |
| 2601 | if (!(mem.eql(u8, options.name, "compiler-rt") or mem.eql(u8, options.name, "zigc"))) { | |
| 2582 | if (!(mem.eql(u8, options.name, "compiler-rt") or mem.eql(u8, options.name, "libc"))) { | |
| 2602 | 2583 | if (options.no_builtin) these_tests.root_module.no_builtin = true; |
| 2603 | 2584 | } |
| 2604 | 2585 | // https://codeberg.org/ziglang/zig/issues/31702 |
| 2605 | if (mem.eql(u8, options.name, "compiler-rt") or mem.eql(u8, options.name, "zigc")) { | |
| 2586 | if (mem.eql(u8, options.name, "compiler-rt") or mem.eql(u8, options.name, "libc")) { | |
| 2606 | 2587 | these_tests.root_module.stack_protector = false; |
| 2607 | 2588 | } |
| 2608 | 2589 | if (options.build_options) |build_options| { |
| ... | ... | @@ -2992,7 +2973,7 @@ pub fn addLlvmIrTests(b: *std.Build, options: LlvmIrContext.Options) ?*Step { |
| 2992 | 2973 | return step; |
| 2993 | 2974 | } |
| 2994 | 2975 | |
| 2995 | const libc_targets: []const std.Target.Query = &.{ | |
| 2976 | const libc_test_nsz_targets: []const std.Target.Query = &.{ | |
| 2996 | 2977 | .{ |
| 2997 | 2978 | .cpu_arch = .arm, |
| 2998 | 2979 | .os_tag = .linux, |
| ... | ... | @@ -3155,8 +3136,8 @@ const libc_targets: []const std.Target.Query = &.{ |
| 3155 | 3136 | }, |
| 3156 | 3137 | }; |
| 3157 | 3138 | |
| 3158 | pub fn addLibcTests(b: *std.Build, options: LibcContext.Options) ?*Step { | |
| 3159 | const step = b.step("test-libc", "Run libc-test test cases"); | |
| 3139 | pub fn addLibcTestNszTests(b: *std.Build, options: LibcContext.Options) ?*Step { | |
| 3140 | const step = b.step("test-libc-nsz", "Run external libc-test test cases"); | |
| 3160 | 3141 | const opt_libc_test_path = b.option(std.Build.LazyPath, "libc-test-path", "path to libc-test source directory"); |
| 3161 | 3142 | if (opt_libc_test_path) |libc_test_path| { |
| 3162 | 3143 | var context: LibcContext = .{ |
| ... | ... | @@ -3168,7 +3149,7 @@ pub fn addLibcTests(b: *std.Build, options: LibcContext.Options) ?*Step { |
| 3168 | 3149 | |
| 3169 | 3150 | libc.addCases(&context); |
| 3170 | 3151 | |
| 3171 | for (libc_targets) |target_query| { | |
| 3152 | for (libc_test_nsz_targets) |target_query| { | |
| 3172 | 3153 | const target = b.resolveTargetQuery(target_query); |
| 3173 | 3154 | context.addTarget(target); |
| 3174 | 3155 | } |