authorgravatar for me@gasinfinity.devGasInfinity <me@gasinfinity.dev> 2026-01-07 12:56:37+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-07 21:53:40+01:00
log335c0fcba1bad1b3b391cdbf8b3b037267a6fee7
tree9c31e03cae945aa7cf325ef1f3dc0cd0c1100d4c
parent62d6bbc7dc36dbb2f45da08e767076157deeb259

feat(libzigc): add `div`, `ldiv`, `lldiv` and `imaxdiv`

* also remove musl implementation

9 files changed, 77 insertions(+), 32 deletions(-)

lib/c/inttypes.zig+14
...@@ -2,11 +2,13 @@ const std = @import("std");...@@ -2,11 +2,13 @@ const std = @import("std");
2const common = @import("common.zig");2const common = @import("common.zig");
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const intmax_t = std.c.intmax_t;4const intmax_t = std.c.intmax_t;
5const imaxdiv_t = std.c.imaxdiv_t;
56
6comptime {7comptime {
7 if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {8 if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
8 // Functions specific to musl and wasi-libc.9 // Functions specific to musl and wasi-libc.
9 @export(&imaxabs, .{ .name = "imaxabs", .linkage = common.linkage, .visibility = common.visibility });10 @export(&imaxabs, .{ .name = "imaxabs", .linkage = common.linkage, .visibility = common.visibility });
11 @export(&imaxdiv, .{ .name = "imaxdiv", .linkage = common.linkage, .visibility = common.visibility });
10 }12 }
11}13}
1214
...@@ -14,7 +16,19 @@ fn imaxabs(a: intmax_t) callconv(.c) intmax_t {...@@ -14,7 +16,19 @@ fn imaxabs(a: intmax_t) callconv(.c) intmax_t {
14 return @intCast(@abs(a));16 return @intCast(@abs(a));
15}17}
1618
19fn imaxdiv(a: intmax_t, b: intmax_t) callconv(.c) imaxdiv_t {
20 return .{
21 .quot = @divTrunc(a, b),
22 .rem = @rem(a, b),
23 };
24}
25
17test imaxabs {26test imaxabs {
18 const val: intmax_t = -10;27 const val: intmax_t = -10;
19 try std.testing.expectEqual(10, imaxabs(val));28 try std.testing.expectEqual(10, imaxabs(val));
20}29}
30
31test imaxdiv {
32 const expected: imaxdiv_t = .{ .quot = 9, .rem = 0 };
33 try std.testing.expectEqual(expected, imaxdiv(9, 1));
34}
lib/c/stdlib.zig+43
...@@ -1,6 +1,9 @@...@@ -1,6 +1,9 @@
1const std = @import("std");1const std = @import("std");
2const common = @import("common.zig");2const common = @import("common.zig");
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const div_t = std.c.div_t;
5const ldiv_t = std.c.ldiv_t;
6const lldiv_t = std.c.lldiv_t;
47
5comptime {8comptime {
6 if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {9 if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
...@@ -9,6 +12,10 @@ comptime {...@@ -9,6 +12,10 @@ comptime {
9 @export(&labs, .{ .name = "labs", .linkage = common.linkage, .visibility = common.visibility });12 @export(&labs, .{ .name = "labs", .linkage = common.linkage, .visibility = common.visibility });
10 @export(&llabs, .{ .name = "llabs", .linkage = common.linkage, .visibility = common.visibility });13 @export(&llabs, .{ .name = "llabs", .linkage = common.linkage, .visibility = common.visibility });
1114
15 @export(&div, .{ .name = "div", .linkage = common.linkage, .visibility = common.visibility });
16 @export(&ldiv, .{ .name = "ldiv", .linkage = common.linkage, .visibility = common.visibility });
17 @export(&lldiv, .{ .name = "lldiv", .linkage = common.linkage, .visibility = common.visibility });
18
12 @export(&qsort_r, .{ .name = "qsort_r", .linkage = common.linkage, .visibility = common.visibility });19 @export(&qsort_r, .{ .name = "qsort_r", .linkage = common.linkage, .visibility = common.visibility });
13 @export(&qsort, .{ .name = "qsort", .linkage = common.linkage, .visibility = common.visibility });20 @export(&qsort, .{ .name = "qsort", .linkage = common.linkage, .visibility = common.visibility });
14 }21 }
...@@ -26,6 +33,27 @@ fn llabs(a: c_longlong) callconv(.c) c_longlong {...@@ -26,6 +33,27 @@ fn llabs(a: c_longlong) callconv(.c) c_longlong {
26 return @intCast(@abs(a));33 return @intCast(@abs(a));
27}34}
2835
36fn div(a: c_int, b: c_int) callconv(.c) div_t {
37 return .{
38 .quot = @divTrunc(a, b),
39 .rem = @rem(a, b),
40 };
41}
42
43fn ldiv(a: c_long, b: c_long) callconv(.c) ldiv_t {
44 return .{
45 .quot = @divTrunc(a, b),
46 .rem = @rem(a, b),
47 };
48}
49
50fn lldiv(a: c_longlong, b: c_longlong) callconv(.c) lldiv_t {
51 return .{
52 .quot = @divTrunc(a, b),
53 .rem = @rem(a, b),
54 };
55}
56
29// NOTE: Despite its name, `qsort` doesn't have to use quicksort or make any complexity or stability guarantee.57// NOTE: Despite its name, `qsort` doesn't have to use quicksort or make any complexity or stability guarantee.
30fn 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 {58fn 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 {
31 const Context = struct {59 const Context = struct {
...@@ -81,3 +109,18 @@ test llabs {...@@ -81,3 +109,18 @@ test llabs {
81 const val: c_longlong = -10;109 const val: c_longlong = -10;
82 try std.testing.expectEqual(10, llabs(val));110 try std.testing.expectEqual(10, llabs(val));
83}111}
112
113test div {
114 const expected: div_t = .{ .quot = 5, .rem = 5 };
115 try std.testing.expectEqual(expected, div(55, 10));
116}
117
118test ldiv {
119 const expected: ldiv_t = .{ .quot = -6, .rem = 2 };
120 try std.testing.expectEqual(expected, ldiv(38, -6));
121}
122
123test lldiv {
124 const expected: lldiv_t = .{ .quot = 1, .rem = 2 };
125 try std.testing.expectEqual(expected, lldiv(5, 3));
126}
lib/libc/musl/src/stdlib/div.c deleted-6
...@@ -1,6 +0,0 @@
1#include <stdlib.h>
2
3div_t div(int num, int den)
4{
5 return (div_t){ num/den, num%den };
6}
lib/libc/musl/src/stdlib/imaxdiv.c deleted-6
...@@ -1,6 +0,0 @@
1#include <inttypes.h>
2
3imaxdiv_t imaxdiv(intmax_t num, intmax_t den)
4{
5 return (imaxdiv_t){ num/den, num%den };
6}
lib/libc/musl/src/stdlib/ldiv.c deleted-6
...@@ -1,6 +0,0 @@
1#include <stdlib.h>
2
3ldiv_t ldiv(long num, long den)
4{
5 return (ldiv_t){ num/den, num%den };
6}
lib/libc/musl/src/stdlib/lldiv.c deleted-6
...@@ -1,6 +0,0 @@
1#include <stdlib.h>
2
3lldiv_t lldiv(long long num, long long den)
4{
5 return (lldiv_t){ num/den, num%den };
6}
lib/std/c.zig+20
...@@ -11051,6 +11051,26 @@ else...@@ -11051,6 +11051,26 @@ else
11051 b: c_longdouble,11051 b: c_longdouble,
11052 };11052 };
1105311053
11054pub const div_t = extern struct {
11055 quot: c_int,
11056 rem: c_int,
11057};
11058
11059pub const ldiv_t = extern struct {
11060 quot: c_long,
11061 rem: c_long,
11062};
11063
11064pub const lldiv_t = extern struct {
11065 quot: c_longlong,
11066 rem: c_longlong,
11067};
11068
11069pub const imaxdiv_t = extern struct {
11070 quot: intmax_t,
11071 rem: intmax_t,
11072};
11073
11054pub const intmax_t = i64;11074pub const intmax_t = i64;
11055pub const uintmax_t = u64;11075pub const uintmax_t = u64;
1105611076
src/libs/musl.zig-4
...@@ -1718,13 +1718,9 @@ const src_files = [_][]const u8{...@@ -1718,13 +1718,9 @@ const src_files = [_][]const u8{
1718 "musl/src/stdlib/atol.c",1718 "musl/src/stdlib/atol.c",
1719 "musl/src/stdlib/atoll.c",1719 "musl/src/stdlib/atoll.c",
1720 "musl/src/stdlib/bsearch.c",1720 "musl/src/stdlib/bsearch.c",
1721 "musl/src/stdlib/div.c",
1722 "musl/src/stdlib/ecvt.c",1721 "musl/src/stdlib/ecvt.c",
1723 "musl/src/stdlib/fcvt.c",1722 "musl/src/stdlib/fcvt.c",
1724 "musl/src/stdlib/gcvt.c",1723 "musl/src/stdlib/gcvt.c",
1725 "musl/src/stdlib/imaxdiv.c",
1726 "musl/src/stdlib/ldiv.c",
1727 "musl/src/stdlib/lldiv.c",
1728 "musl/src/stdlib/strtod.c",1724 "musl/src/stdlib/strtod.c",
1729 "musl/src/stdlib/strtol.c",1725 "musl/src/stdlib/strtol.c",
1730 "musl/src/stdlib/wcstod.c",1726 "musl/src/stdlib/wcstod.c",
src/libs/wasi_libc.zig-4
...@@ -1008,13 +1008,9 @@ const libc_top_half_src_files = [_][]const u8{...@@ -1008,13 +1008,9 @@ const libc_top_half_src_files = [_][]const u8{
1008 "musl/src/stdlib/atol.c",1008 "musl/src/stdlib/atol.c",
1009 "musl/src/stdlib/atoll.c",1009 "musl/src/stdlib/atoll.c",
1010 "musl/src/stdlib/bsearch.c",1010 "musl/src/stdlib/bsearch.c",
1011 "musl/src/stdlib/div.c",
1012 "musl/src/stdlib/ecvt.c",1011 "musl/src/stdlib/ecvt.c",
1013 "musl/src/stdlib/fcvt.c",1012 "musl/src/stdlib/fcvt.c",
1014 "musl/src/stdlib/gcvt.c",1013 "musl/src/stdlib/gcvt.c",
1015 "musl/src/stdlib/imaxdiv.c",
1016 "musl/src/stdlib/ldiv.c",
1017 "musl/src/stdlib/lldiv.c",
1018 "musl/src/stdlib/strtol.c",1014 "musl/src/stdlib/strtol.c",
1019 "musl/src/string/bcopy.c",1015 "musl/src/string/bcopy.c",
1020 "musl/src/string/explicit_bzero.c",1016 "musl/src/string/explicit_bzero.c",