| ... | ... | @@ -26,6 +26,7 @@ comptime { |
| 26 | 26 | @export(&wcsspn, .{ .name = "wcsspn", .linkage = common.linkage, .visibility = common.visibility }); |
| 27 | 27 | @export(&wcscspn, .{ .name = "wcscspn", .linkage = common.linkage, .visibility = common.visibility }); |
| 28 | 28 | @export(&wcspbrk, .{ .name = "wcspbrk", .linkage = common.linkage, .visibility = common.visibility }); |
| 29 | @export(&wcstok, .{ .name = "wcstok", .linkage = common.linkage, .visibility = common.visibility }); |
| 29 | 30 | @export(&wcsstr, .{ .name = "wcsstr", .linkage = common.linkage, .visibility = common.visibility }); |
| 30 | 31 | @export(&wcswcs, .{ .name = "wcswcs", .linkage = common.linkage, .visibility = common.visibility }); |
| 31 | 32 | } |
| ... | ... | @@ -46,10 +47,8 @@ fn wmemchr(ptr: [*]const wchar_t, value: wchar_t, len: usize) callconv(.c) ?[*]w |
| 46 | 47 | } |
| 47 | 48 | |
| 48 | 49 | fn wmemcmp(a: [*]const wchar_t, b: [*]const wchar_t, len: usize) callconv(.c) c_int { |
| 49 | | const idx = std.mem.findDiff(wchar_t, a[0..len], b[0..len]) orelse return 0; |
| 50 | | |
| 51 | | return switch (std.math.order(a[idx], b[idx])) { |
| 52 | | .eq => unreachable, |
| 50 | return switch (std.mem.order(wchar_t, a[0..len], b[0..len])) { |
| 51 | .eq => 0, |
| 53 | 52 | .gt => 1, |
| 54 | 53 | .lt => -1, |
| 55 | 54 | }; |
| ... | ... | @@ -88,40 +87,24 @@ fn wcscmp(a: [*:0]const wchar_t, b: [*:0]const wchar_t) callconv(.c) c_int { |
| 88 | 87 | } |
| 89 | 88 | |
| 90 | 89 | fn wcsncmp(a: [*:0]const wchar_t, b: [*:0]const wchar_t, max: usize) callconv(.c) c_int { |
| 91 | | const a_slice = a[0..wcsnlen(a, max)]; |
| 92 | | const b_slice = b[0..wcsnlen(b, max)]; |
| 93 | | |
| 94 | | return switch (std.math.order(a_slice.len, b_slice.len)) { |
| 95 | | .eq => blk: { |
| 96 | | const idx = std.mem.findDiff(wchar_t, a_slice, b_slice) orelse break :blk 0; |
| 97 | | |
| 98 | | break :blk switch (std.math.order(a[idx], b[idx])) { |
| 99 | | .eq => unreachable, |
| 100 | | .gt => 1, |
| 101 | | .lt => -1, |
| 102 | | }; |
| 103 | | }, |
| 90 | return switch (std.mem.boundedOrderZ(wchar_t, a, b, max)) { |
| 91 | .eq => 0, |
| 104 | 92 | .gt => 1, |
| 105 | 93 | .lt => -1, |
| 106 | 94 | }; |
| 107 | 95 | } |
| 108 | 96 | |
| 109 | 97 | fn wcpcpy(noalias dst: [*]wchar_t, noalias src: [*:0]const wchar_t) callconv(.c) [*]wchar_t { |
| 110 | | const src_slice = std.mem.span(src); |
| 111 | | @memcpy(dst[0..src_slice.len], src_slice); |
| 112 | | dst[src_slice.len] = 0; |
| 113 | | return dst + src_slice.len; |
| 114 | | // XXX: LLVM bug? |
| 115 | | // return wcpncpy(dst, src, std.math.maxInt(usize)); |
| 98 | const src_len = std.mem.len(src); |
| 99 | @memcpy(dst[0 .. src_len + 1], src[0 .. src_len + 1]); |
| 100 | return dst + src_len; |
| 116 | 101 | } |
| 117 | 102 | |
| 118 | 103 | fn wcpncpy(noalias dst: [*]wchar_t, noalias src: [*:0]const wchar_t, max: usize) callconv(.c) [*]wchar_t { |
| 119 | 104 | const src_len = wcsnlen(src, max); |
| 120 | 105 | const copying_len = @min(max, src_len); |
| 121 | | |
| 122 | 106 | @memcpy(dst[0..copying_len], src[0..copying_len]); |
| 123 | | |
| 124 | | if (copying_len < max) dst[copying_len] = 0; |
| 107 | @memset(dst[copying_len..][0 .. max - copying_len], 0x00); |
| 125 | 108 | return dst + copying_len; |
| 126 | 109 | } |
| 127 | 110 | |
| ... | ... | @@ -175,6 +158,28 @@ fn wcspbrk(haystack: [*:0]const wchar_t, needle: [*:0]const wchar_t) callconv(.c |
| 175 | 158 | return @constCast(haystack[std.mem.findAny(wchar_t, std.mem.span(haystack), std.mem.span(needle)) orelse return null ..]); |
| 176 | 159 | } |
| 177 | 160 | |
| 161 | fn wcstok(noalias maybe_str: ?[*:0]wchar_t, noalias values: [*:0]const wchar_t, noalias state: *?[*:0]wchar_t) callconv(.c) ?[*:0]wchar_t { |
| 162 | const str = if (maybe_str) |str| |
| 163 | str |
| 164 | else if (state.*) |state_str| |
| 165 | state_str |
| 166 | else |
| 167 | return null; |
| 168 | |
| 169 | const str_chars = std.mem.span(str); |
| 170 | const values_chars = std.mem.span(values); |
| 171 | const tok_start = std.mem.findNone(wchar_t, str_chars, values_chars) orelse return null; |
| 172 | |
| 173 | if (std.mem.findAnyPos(wchar_t, str_chars, tok_start, values_chars)) |tok_end| { |
| 174 | str[tok_end] = 0; |
| 175 | state.* = str[tok_end + 1 ..]; |
| 176 | } else { |
| 177 | state.* = str[str_chars.len..]; |
| 178 | } |
| 179 | |
| 180 | return str[tok_start..]; |
| 181 | } |
| 182 | |
| 178 | 183 | fn wcsstr(noalias haystack: [*:0]const wchar_t, noalias needle: [*:0]const wchar_t) callconv(.c) ?[*:0]wchar_t { |
| 179 | 184 | return @constCast(haystack[std.mem.find(wchar_t, std.mem.span(haystack), std.mem.span(needle)) orelse return null ..]); |
| 180 | 185 | } |