1const builtin = @import("builtin");
2const std = @import("std");
3const symbol = @import("../c.zig").symbol;
4
5comptime {
6 if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
7 // bcmp is implemented in compiler_rt
8 symbol(&bcopy, "bcopy");
9 symbol(&bzero, "bzero");
10 symbol(&index, "index");
11 symbol(&rindex, "rindex");
12
13 symbol(&ffs, "ffs");
14 symbol(&ffsl, "ffsl");
15 symbol(&ffsll, "ffsll");
16
17 symbol(&strcasecmp, "strcasecmp");
18 symbol(&strncasecmp, "strncasecmp");
19
20 symbol(&__strcasecmp_l, "__strcasecmp_l");
21 symbol(&__strncasecmp_l, "__strncasecmp_l");
22
23 symbol(&__strcasecmp_l, "strcasecmp_l");
24 symbol(&__strncasecmp_l, "strncasecmp_l");
25 }
26}
27
28fn bcopy(src: *const anyopaque, dst: *anyopaque, len: usize) callconv(.c) void {
29 const src_bytes: [*]const u8 = @ptrCast(src);
30 const dst_bytes: [*]u8 = @ptrCast(dst);
31 @memmove(dst_bytes[0..len], src_bytes[0..len]);
32}
33
34fn bzero(s: *anyopaque, n: usize) callconv(.c) void {
35 const s_cast: [*]u8 = @ptrCast(s);
36 @memset(s_cast[0..n], 0);
37}
38
39fn index(str: [*:0]const c_char, value: c_int) callconv(.c) ?[*:0]c_char {
40 return @constCast(str[std.mem.findScalar(u8, std.mem.span(@as([*:0]const u8, @ptrCast(str))), @truncate(@as(c_uint, @bitCast(value)))) orelse return null ..]);
41}
42
43fn 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 ..]);
45}
46
47fn firstBitSet(comptime T: type, value: T) T {
48 return @bitSizeOf(T) - @clz(value);
49}
50
51fn ffs(i: c_int) callconv(.c) c_int {
52 return firstBitSet(c_int, i);
53}
54
55fn ffsl(i: c_long) callconv(.c) c_long {
56 return firstBitSet(c_long, i);
57}
58
59fn ffsll(i: c_longlong) callconv(.c) c_longlong {
60 return firstBitSet(c_longlong, i);
61}
62
63fn strcasecmp(a: [*:0]const c_char, b: [*:0]const c_char) callconv(.c) c_int {
64 return strncasecmp(a, b, std.math.maxInt(usize));
65}
66
67fn __strcasecmp_l(a: [*:0]const c_char, b: [*:0]const c_char, locale: *anyopaque) callconv(.c) c_int {
68 _ = locale;
69 return strcasecmp(a, b);
70}
71
72fn strncasecmp(a: [*:0]const c_char, b: [*:0]const c_char, max: usize) callconv(.c) c_int {
73 return switch (std.ascii.boundedOrderIgnoreCaseZ(@ptrCast(a), @ptrCast(b), max)) {
74 .eq => 0,
75 .gt => 1,
76 .lt => -1,
77 };
78}
79
80fn __strncasecmp_l(a: [*:0]const c_char, b: [*:0]const c_char, n: usize, locale: *anyopaque) callconv(.c) c_int {
81 _ = locale;
82 return strncasecmp(a, b, n);
83}