| ... | @@ -26,6 +26,7 @@ comptime { | ... | @@ -26,6 +26,7 @@ comptime { |
| 26 | @export(&wcsspn, .{ .name = "wcsspn", .linkage = common.linkage, .visibility = common.visibility }); | 26 | @export(&wcsspn, .{ .name = "wcsspn", .linkage = common.linkage, .visibility = common.visibility }); |
| 27 | @export(&wcscspn, .{ .name = "wcscspn", .linkage = common.linkage, .visibility = common.visibility }); | 27 | @export(&wcscspn, .{ .name = "wcscspn", .linkage = common.linkage, .visibility = common.visibility }); |
| 28 | @export(&wcspbrk, .{ .name = "wcspbrk", .linkage = common.linkage, .visibility = common.visibility }); | 28 | @export(&wcspbrk, .{ .name = "wcspbrk", .linkage = common.linkage, .visibility = common.visibility }); |
| | 29 | @export(&wcstok, .{ .name = "wcstok", .linkage = common.linkage, .visibility = common.visibility }); |
| 29 | @export(&wcsstr, .{ .name = "wcsstr", .linkage = common.linkage, .visibility = common.visibility }); | 30 | @export(&wcsstr, .{ .name = "wcsstr", .linkage = common.linkage, .visibility = common.visibility }); |
| 30 | @export(&wcswcs, .{ .name = "wcswcs", .linkage = common.linkage, .visibility = common.visibility }); | 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,10 +47,8 @@ fn wmemchr(ptr: [*]const wchar_t, value: wchar_t, len: usize) callconv(.c) ?[*]w |
| 46 | } | 47 | } |
| 47 | | 48 | |
| 48 | fn wmemcmp(a: [*]const wchar_t, b: [*]const wchar_t, len: usize) callconv(.c) c_int { | 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 | return switch (std.mem.order(wchar_t, a[0..len], b[0..len])) { |
| 50 | | 51 | .eq => 0, |
| 51 | return switch (std.math.order(a[idx], b[idx])) { | | |
| 52 | .eq => unreachable, | | |
| 53 | .gt => 1, | 52 | .gt => 1, |
| 54 | .lt => -1, | 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,40 +87,24 @@ fn wcscmp(a: [*:0]const wchar_t, b: [*:0]const wchar_t) callconv(.c) c_int { |
| 88 | } | 87 | } |
| 89 | | 88 | |
| 90 | fn wcsncmp(a: [*:0]const wchar_t, b: [*:0]const wchar_t, max: usize) callconv(.c) c_int { | 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)]; | 90 | return switch (std.mem.boundedOrderZ(wchar_t, a, b, max)) { |
| 92 | const b_slice = b[0..wcsnlen(b, max)]; | 91 | .eq => 0, |
| 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 | }, | | |
| 104 | .gt => 1, | 92 | .gt => 1, |
| 105 | .lt => -1, | 93 | .lt => -1, |
| 106 | }; | 94 | }; |
| 107 | } | 95 | } |
| 108 | | 96 | |
| 109 | fn wcpcpy(noalias dst: [*]wchar_t, noalias src: [*:0]const wchar_t) callconv(.c) [*]wchar_t { | 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); | 98 | const src_len = std.mem.len(src); |
| 111 | @memcpy(dst[0..src_slice.len], src_slice); | 99 | @memcpy(dst[0 .. src_len + 1], src[0 .. src_len + 1]); |
| 112 | dst[src_slice.len] = 0; | 100 | return dst + src_len; |
| 113 | return dst + src_slice.len; | | |
| 114 | // XXX: LLVM bug? | | |
| 115 | // return wcpncpy(dst, src, std.math.maxInt(usize)); | | |
| 116 | } | 101 | } |
| 117 | | 102 | |
| 118 | fn wcpncpy(noalias dst: [*]wchar_t, noalias src: [*:0]const wchar_t, max: usize) callconv(.c) [*]wchar_t { | 103 | fn wcpncpy(noalias dst: [*]wchar_t, noalias src: [*:0]const wchar_t, max: usize) callconv(.c) [*]wchar_t { |
| 119 | const src_len = wcsnlen(src, max); | 104 | const src_len = wcsnlen(src, max); |
| 120 | const copying_len = @min(max, src_len); | 105 | const copying_len = @min(max, src_len); |
| 121 | | | |
| 122 | @memcpy(dst[0..copying_len], src[0..copying_len]); | 106 | @memcpy(dst[0..copying_len], src[0..copying_len]); |
| 123 | | 107 | @memset(dst[copying_len..][0 .. max - copying_len], 0x00); |
| 124 | if (copying_len < max) dst[copying_len] = 0; | | |
| 125 | return dst + copying_len; | 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,6 +158,28 @@ fn wcspbrk(haystack: [*:0]const wchar_t, needle: [*:0]const wchar_t) callconv(.c |
| 175 | return @constCast(haystack[std.mem.findAny(wchar_t, std.mem.span(haystack), std.mem.span(needle)) orelse return null ..]); | 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 | fn wcsstr(noalias haystack: [*:0]const wchar_t, noalias needle: [*:0]const wchar_t) callconv(.c) ?[*:0]wchar_t { | 183 | fn wcsstr(noalias haystack: [*:0]const wchar_t, noalias needle: [*:0]const wchar_t) callconv(.c) ?[*:0]wchar_t { |
| 179 | return @constCast(haystack[std.mem.find(wchar_t, std.mem.span(haystack), std.mem.span(needle)) orelse return null ..]); | 184 | return @constCast(haystack[std.mem.find(wchar_t, std.mem.span(haystack), std.mem.span(needle)) orelse return null ..]); |
| 180 | } | 185 | } |