authorgravatar for ivel.santos@proton.meIvel <ivel.santos@proton.me> 2026-02-05 20:21:41+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-05 20:21:41+01:00
logfa3228ae42d3bc92ad66fe91e108511583129ffd
treed29d7d2bd80dfc23387850a509a83be906a795f3
parentc77e7146f5fa8e83c06cd6612b7298df06912974

libc: reimplement swab in Zig (#31130)

This PR replaces the bundled musl swab() implementation with zig's one. Contributes towards #30978. It looks like there are not test cases for swab() in test-libc. Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31130 Reviewed-by: Andrew Kelley <andrew@ziglang.org> Co-authored-by: Ivel <ivel.santos@proton.me> Co-committed-by: Ivel <ivel.santos@proton.me>

4 files changed, 42 insertions(+), 15 deletions(-)

lib/c/unistd.zig+42
......@@ -43,6 +43,9 @@ comptime {
4343
4444 @export(&execveLinux, .{ .name = "execve", .linkage = common.linkage, .visibility = common.visibility });
4545 }
46 if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
47 @export(&swab, .{ .name = "swab", .linkage = common.linkage, .visibility = common.visibility });
48 }
4649}
4750
4851fn _exit(exit_code: c_int) callconv(.c) noreturn {
......@@ -181,3 +184,42 @@ fn unlinkatLinux(fd: c_int, path: [*:0]const c_char, flags: c_int) callconv(.c)
181184fn execveLinux(path: [*:0]const c_char, argv: [*:null]const ?[*:0]c_char, envp: [*:null]const ?[*:0]c_char) callconv(.c) c_int {
182185 return common.errno(linux.execve(@ptrCast(path), @ptrCast(argv), @ptrCast(envp)));
183186}
187
188fn swab(noalias src_ptr: *const anyopaque, noalias dest_ptr: *anyopaque, n: isize) callconv(.c) void {
189 var src: [*]const u8 = @ptrCast(src_ptr);
190 var dest: [*]u8 = @ptrCast(dest_ptr);
191 var i = n;
192
193 while (i > 1) : (i -= 2) {
194 dest[0] = src[1];
195 dest[1] = src[0];
196 dest += 2;
197 src += 2;
198 }
199}
200
201test swab {
202 var a: [4]u8 = undefined;
203 @memset(a[0..], '\x00');
204 swab("abcd", &a, 4);
205 try std.testing.expectEqualSlices(u8, "badc", &a);
206
207 // Partial copy
208 @memset(a[0..], '\x00');
209 swab("abcd", &a, 2);
210 try std.testing.expectEqualSlices(u8, "ba\x00\x00", &a);
211
212 // n < 1
213 @memset(a[0..], '\x00');
214 swab("abcd", &a, 0);
215 try std.testing.expectEqualSlices(u8, "\x00" ** 4, &a);
216 swab("abcd", &a, -1);
217 try std.testing.expectEqualSlices(u8, "\x00" ** 4, &a);
218
219 // Odd n
220 @memset(a[0..], '\x00');
221 swab("abcd", &a, 1);
222 try std.testing.expectEqualSlices(u8, "\x00" ** 4, &a);
223 swab("abcd", &a, 3);
224 try std.testing.expectEqualSlices(u8, "ba\x00\x00", &a);
225}
lib/libc/musl/src/string/swab.c deleted-13
......@@ -1,13 +0,0 @@
1#include <unistd.h>
2
3void swab(const void *restrict _src, void *restrict _dest, ssize_t n)
4{
5 const char *src = _src;
6 char *dest = _dest;
7 for (; n>1; n-=2) {
8 dest[0] = src[1];
9 dest[1] = src[0];
10 dest += 2;
11 src += 2;
12 }
13}
src/libs/musl.zig-1
......@@ -1579,7 +1579,6 @@ const src_files = [_][]const u8{
15791579 "musl/src/string/strndup.c",
15801580 "musl/src/string/strsignal.c",
15811581 "musl/src/string/strverscmp.c",
1582 "musl/src/string/swab.c",
15831582 "musl/src/string/wcscasecmp.c",
15841583 "musl/src/string/wcscasecmp_l.c",
15851584 "musl/src/string/wcsdup.c",
src/libs/wasi_libc.zig-1
......@@ -957,7 +957,6 @@ const libc_top_half_src_files = [_][]const u8{
957957 "musl/src/string/strerror_r.c",
958958 "musl/src/string/strndup.c",
959959 "musl/src/string/strverscmp.c",
960 "musl/src/string/swab.c",
961960 "musl/src/string/wcscasecmp.c",
962961 "musl/src/string/wcscasecmp_l.c",
963962 "musl/src/string/wcsdup.c",