authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-13 20:06:22+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-15 22:58:53+02:00
log8b52a7c0c5a602439b13d7791902777bfe80d454
tree8e6fc208b9f09ea29a64b1a89eb2ea6a0c99729e
parent9c011c6a40e31995839bbea226715062bc5e07eb

std.c, libzigc: fix ffs() family signatures and implementation bugs


3 files changed, 8 insertions(+), 12 deletions(-)

lib/c/strings.zig+4-4
...@@ -44,19 +44,19 @@ fn rindex(str: [*:0]const c_char, value: c_int) callconv(.c) ?[*:0]c_char {...@@ -44,19 +44,19 @@ fn rindex(str: [*:0]const c_char, value: c_int) callconv(.c) ?[*:0]c_char {
44 return @constCast(str[std.mem.findScalarLast(u8, std.mem.span(@as([*:0]const u8, @ptrCast(str))), @truncate(@as(c_uint, @bitCast(value)))) orelse return null ..]);44 return @constCast(str[std.mem.findScalarLast(u8, std.mem.span(@as([*:0]const u8, @ptrCast(str))), @truncate(@as(c_uint, @bitCast(value)))) orelse return null ..]);
45}45}
4646
47fn firstBitSet(comptime T: type, value: T) T {47fn firstBitSet(comptime T: type, value: T) c_int {
48 return @bitSizeOf(T) - @clz(value);48 return if (value == 0) 0 else @as(c_int, @ctz(value)) + 1;
49}49}
5050
51fn ffs(i: c_int) callconv(.c) c_int {51fn ffs(i: c_int) callconv(.c) c_int {
52 return firstBitSet(c_int, i);52 return firstBitSet(c_int, i);
53}53}
5454
55fn ffsl(i: c_long) callconv(.c) c_long {55fn ffsl(i: c_long) callconv(.c) c_int {
56 return firstBitSet(c_long, i);56 return firstBitSet(c_long, i);
57}57}
5858
59fn ffsll(i: c_longlong) callconv(.c) c_longlong {59fn ffsll(i: c_longlong) callconv(.c) c_int {
60 return firstBitSet(c_longlong, i);60 return firstBitSet(c_longlong, i);
61}61}
6262
lib/std/c.zig+2-2
...@@ -11377,8 +11377,8 @@ pub const wcsdup = switch (builtin.abi) {...@@ -11377,8 +11377,8 @@ pub const wcsdup = switch (builtin.abi) {
11377};11377};
1137811378
11379pub extern "c" fn ffs(i: c_int) c_int;11379pub extern "c" fn ffs(i: c_int) c_int;
11380pub extern "c" fn ffsl(i: c_long) c_long;11380pub extern "c" fn ffsl(i: c_long) c_int;
11381pub extern "c" fn ffsll(i: c_longlong) c_longlong;11381pub extern "c" fn ffsll(i: c_longlong) c_int;
1138211382
11383pub extern "c" fn erand48(xsubi: *[3]c_ushort) f64;11383pub extern "c" fn erand48(xsubi: *[3]c_ushort) f64;
11384pub extern "c" fn jrand48(xsubi: *[3]c_ushort) c_long;11384pub extern "c" fn jrand48(xsubi: *[3]c_ushort) c_long;
test/c/strings.zig+2-6
...@@ -26,9 +26,8 @@ fn testFfs(comptime T: type) !void {...@@ -26,9 +26,8 @@ fn testFfs(comptime T: type) !void {
26 try testing.expectEqual(0, ffs(0));26 try testing.expectEqual(0, ffs(0));
2727
28 for (0..@bitSizeOf(T)) |i| {28 for (0..@bitSizeOf(T)) |i| {
29 const bit = @as(T, 1) << @intCast(i);29 try testing.expectEqual(@as(c_int, @intCast(i + 1)), ffs(@as(T, 1) << @intCast(i)));
3030 try testing.expectEqual(@as(c_int, @intCast(i + 1)), ffs(@as(T, -1) << @intCast(i)));
31 try testing.expectEqual(@as(T, @intCast(i + 1)), ffs(bit));
32 }31 }
33}32}
3433
...@@ -41,9 +40,6 @@ test "ffs" {...@@ -41,9 +40,6 @@ test "ffs" {
41 if (builtin.target.os.tag == .netbsd) return; // no ffsl/ffsll until 1140 if (builtin.target.os.tag == .netbsd) return; // no ffsl/ffsll until 11
4241
43 try testFfs(c_long);42 try testFfs(c_long);
44
45 if (@sizeOf(usize) == 4) return error.SkipZigTest; // TODO
46
47 try testFfs(c_longlong);43 try testFfs(c_longlong);
48}44}
4945