diff --git a/lib/c/inttypes.zig b/lib/c/inttypes.zig index 34de671d0cfe96a046b120ee0dc8f9f9ac7442dd..39b2c9ba885008e8307c2d01f5b84eff3fc1f91a 100644 --- a/lib/c/inttypes.zig +++ b/lib/c/inttypes.zig @@ -2,11 +2,13 @@ const std = @import("std"); const common = @import("common.zig"); const builtin = @import("builtin"); const intmax_t = std.c.intmax_t; +const imaxdiv_t = std.c.imaxdiv_t; comptime { if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) { // Functions specific to musl and wasi-libc. @export(&imaxabs, .{ .name = "imaxabs", .linkage = common.linkage, .visibility = common.visibility }); + @export(&imaxdiv, .{ .name = "imaxdiv", .linkage = common.linkage, .visibility = common.visibility }); } } @@ -14,7 +16,19 @@ fn imaxabs(a: intmax_t) callconv(.c) intmax_t { return @intCast(@abs(a)); } +fn imaxdiv(a: intmax_t, b: intmax_t) callconv(.c) imaxdiv_t { + return .{ + .quot = @divTrunc(a, b), + .rem = @rem(a, b), + }; +} + test imaxabs { const val: intmax_t = -10; try std.testing.expectEqual(10, imaxabs(val)); } + +test imaxdiv { + const expected: imaxdiv_t = .{ .quot = 9, .rem = 0 }; + try std.testing.expectEqual(expected, imaxdiv(9, 1)); +} diff --git a/lib/c/stdlib.zig b/lib/c/stdlib.zig index f764f166cbc7848a0826dbff6f931ea6db618ee5..85e3a85b86f0fd9a2654dfe4eb1b09c3e1b5d08d 100644 --- a/lib/c/stdlib.zig +++ b/lib/c/stdlib.zig @@ -1,6 +1,9 @@ const std = @import("std"); const common = @import("common.zig"); const builtin = @import("builtin"); +const div_t = std.c.div_t; +const ldiv_t = std.c.ldiv_t; +const lldiv_t = std.c.lldiv_t; comptime { if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) { @@ -9,6 +12,10 @@ comptime { @export(&labs, .{ .name = "labs", .linkage = common.linkage, .visibility = common.visibility }); @export(&llabs, .{ .name = "llabs", .linkage = common.linkage, .visibility = common.visibility }); + @export(&div, .{ .name = "div", .linkage = common.linkage, .visibility = common.visibility }); + @export(&ldiv, .{ .name = "ldiv", .linkage = common.linkage, .visibility = common.visibility }); + @export(&lldiv, .{ .name = "lldiv", .linkage = common.linkage, .visibility = common.visibility }); + @export(&qsort_r, .{ .name = "qsort_r", .linkage = common.linkage, .visibility = common.visibility }); @export(&qsort, .{ .name = "qsort", .linkage = common.linkage, .visibility = common.visibility }); } @@ -26,6 +33,27 @@ fn llabs(a: c_longlong) callconv(.c) c_longlong { return @intCast(@abs(a)); } +fn div(a: c_int, b: c_int) callconv(.c) div_t { + return .{ + .quot = @divTrunc(a, b), + .rem = @rem(a, b), + }; +} + +fn ldiv(a: c_long, b: c_long) callconv(.c) ldiv_t { + return .{ + .quot = @divTrunc(a, b), + .rem = @rem(a, b), + }; +} + +fn lldiv(a: c_longlong, b: c_longlong) callconv(.c) lldiv_t { + return .{ + .quot = @divTrunc(a, b), + .rem = @rem(a, b), + }; +} + // NOTE: Despite its name, `qsort` doesn't have to use quicksort or make any complexity or stability guarantee. fn qsort_r(base: *anyopaque, n: usize, size: usize, compare: *const fn (a: *const anyopaque, b: *const anyopaque, arg: ?*anyopaque) callconv(.c) c_int, arg: ?*anyopaque) callconv(.c) void { const Context = struct { @@ -81,3 +109,18 @@ test llabs { const val: c_longlong = -10; try std.testing.expectEqual(10, llabs(val)); } + +test div { + const expected: div_t = .{ .quot = 5, .rem = 5 }; + try std.testing.expectEqual(expected, div(55, 10)); +} + +test ldiv { + const expected: ldiv_t = .{ .quot = -6, .rem = 2 }; + try std.testing.expectEqual(expected, ldiv(38, -6)); +} + +test lldiv { + const expected: lldiv_t = .{ .quot = 1, .rem = 2 }; + try std.testing.expectEqual(expected, lldiv(5, 3)); +} diff --git a/lib/libc/musl/src/stdlib/div.c b/lib/libc/musl/src/stdlib/div.c deleted file mode 100644 index e42c1f14fa49464a606e17b8f142ef3c882c23a7..0000000000000000000000000000000000000000 --- a/lib/libc/musl/src/stdlib/div.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -div_t div(int num, int den) -{ - return (div_t){ num/den, num%den }; -} diff --git a/lib/libc/musl/src/stdlib/imaxdiv.c b/lib/libc/musl/src/stdlib/imaxdiv.c deleted file mode 100644 index b2ce821f51e3e2428e773e2e9eae6c2156157fb6..0000000000000000000000000000000000000000 --- a/lib/libc/musl/src/stdlib/imaxdiv.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -imaxdiv_t imaxdiv(intmax_t num, intmax_t den) -{ - return (imaxdiv_t){ num/den, num%den }; -} diff --git a/lib/libc/musl/src/stdlib/ldiv.c b/lib/libc/musl/src/stdlib/ldiv.c deleted file mode 100644 index 36eb960b09784f12013d34d9b28a16d2a4e1c296..0000000000000000000000000000000000000000 --- a/lib/libc/musl/src/stdlib/ldiv.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -ldiv_t ldiv(long num, long den) -{ - return (ldiv_t){ num/den, num%den }; -} diff --git a/lib/libc/musl/src/stdlib/lldiv.c b/lib/libc/musl/src/stdlib/lldiv.c deleted file mode 100644 index 7aaf7a0e6f24be999a824fe5b40750e346b66603..0000000000000000000000000000000000000000 --- a/lib/libc/musl/src/stdlib/lldiv.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -lldiv_t lldiv(long long num, long long den) -{ - return (lldiv_t){ num/den, num%den }; -} diff --git a/lib/std/c.zig b/lib/std/c.zig index 3eea82d3da7edc361681b1608cd1876ac5e0e671..e1a4def3687f82b41c3d7e9b56062a549466561a 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -11051,6 +11051,26 @@ else b: c_longdouble, }; +pub const div_t = extern struct { + quot: c_int, + rem: c_int, +}; + +pub const ldiv_t = extern struct { + quot: c_long, + rem: c_long, +}; + +pub const lldiv_t = extern struct { + quot: c_longlong, + rem: c_longlong, +}; + +pub const imaxdiv_t = extern struct { + quot: intmax_t, + rem: intmax_t, +}; + pub const intmax_t = i64; pub const uintmax_t = u64; diff --git a/src/libs/musl.zig b/src/libs/musl.zig index e1a41aa02b148d3d197b52c5db0f049e9fb15472..0eb1f919c9a6f6421631c9cdb35b024cefa20078 100644 --- a/src/libs/musl.zig +++ b/src/libs/musl.zig @@ -1718,13 +1718,9 @@ const src_files = [_][]const u8{ "musl/src/stdlib/atol.c", "musl/src/stdlib/atoll.c", "musl/src/stdlib/bsearch.c", - "musl/src/stdlib/div.c", "musl/src/stdlib/ecvt.c", "musl/src/stdlib/fcvt.c", "musl/src/stdlib/gcvt.c", - "musl/src/stdlib/imaxdiv.c", - "musl/src/stdlib/ldiv.c", - "musl/src/stdlib/lldiv.c", "musl/src/stdlib/strtod.c", "musl/src/stdlib/strtol.c", "musl/src/stdlib/wcstod.c", diff --git a/src/libs/wasi_libc.zig b/src/libs/wasi_libc.zig index 789dfa9c302ca3356f4c668d0c01f320df809d29..ebfd3f6475e80e2e9e931e8a6be7a3db229dc50d 100644 --- a/src/libs/wasi_libc.zig +++ b/src/libs/wasi_libc.zig @@ -1008,13 +1008,9 @@ const libc_top_half_src_files = [_][]const u8{ "musl/src/stdlib/atol.c", "musl/src/stdlib/atoll.c", "musl/src/stdlib/bsearch.c", - "musl/src/stdlib/div.c", "musl/src/stdlib/ecvt.c", "musl/src/stdlib/fcvt.c", "musl/src/stdlib/gcvt.c", - "musl/src/stdlib/imaxdiv.c", - "musl/src/stdlib/ldiv.c", - "musl/src/stdlib/lldiv.c", "musl/src/stdlib/strtol.c", "musl/src/string/bcopy.c", "musl/src/string/explicit_bzero.c",