Merge pull request 'libc: use common implementations for wchar.h' (#30850) from GasInfinity/zig:libc-wchar into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30850
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
This commit is contained in:
Andrew Kelley
2026-01-17 00:58:01 +01:00
35 changed files with 195 additions and 550 deletions
+1
View File
@@ -18,6 +18,7 @@ comptime {
_ = @import("c/ctype.zig");
_ = @import("c/stdlib.zig");
_ = @import("c/math.zig");
_ = @import("c/wchar.zig");
if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
// Files specific to musl and wasi-libc.
+184
View File
@@ -0,0 +1,184 @@
const std = @import("std");
const common = @import("common.zig");
const builtin = @import("builtin");
const wint_t = std.c.wint_t;
const wchar_t = std.c.wchar_t;
comptime {
if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
@export(&wmemchr, .{ .name = "wmemchr", .linkage = common.linkage, .visibility = common.visibility });
@export(&wmemcmp, .{ .name = "wmemcmp", .linkage = common.linkage, .visibility = common.visibility });
@export(&wmemcpy, .{ .name = "wmemcpy", .linkage = common.linkage, .visibility = common.visibility });
@export(&wmemmove, .{ .name = "wmemmove", .linkage = common.linkage, .visibility = common.visibility });
@export(&wmemset, .{ .name = "wmemset", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcslen, .{ .name = "wcslen", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcsnlen, .{ .name = "wcsnlen", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcscmp, .{ .name = "wcscmp", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcsncmp, .{ .name = "wcsncmp", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcpcpy, .{ .name = "wcpcpy", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcpncpy, .{ .name = "wcpncpy", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcscpy, .{ .name = "wcscpy", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcsncpy, .{ .name = "wcsncpy", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcscat, .{ .name = "wcscat", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcsncat, .{ .name = "wcsncat", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcschr, .{ .name = "wcschr", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcsrchr, .{ .name = "wcsrchr", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcsspn, .{ .name = "wcsspn", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcscspn, .{ .name = "wcscspn", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcspbrk, .{ .name = "wcspbrk", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcsstr, .{ .name = "wcsstr", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcswcs, .{ .name = "wcswcs", .linkage = common.linkage, .visibility = common.visibility });
}
if (builtin.target.isMinGW()) {
@export(&wmemchr, .{ .name = "wmemchr", .linkage = common.linkage, .visibility = common.visibility });
@export(&wmemcmp, .{ .name = "wmemcmp", .linkage = common.linkage, .visibility = common.visibility });
@export(&wmemcpy, .{ .name = "wmemcpy", .linkage = common.linkage, .visibility = common.visibility });
@export(&wmempcpy, .{ .name = "wmempcpy", .linkage = common.linkage, .visibility = common.visibility });
@export(&wmemmove, .{ .name = "wmemmove", .linkage = common.linkage, .visibility = common.visibility });
@export(&wmemset, .{ .name = "wmemset", .linkage = common.linkage, .visibility = common.visibility });
@export(&wcsnlen, .{ .name = "wcsnlen", .linkage = common.linkage, .visibility = common.visibility });
}
}
fn wmemchr(ptr: [*]const wchar_t, value: wchar_t, len: usize) callconv(.c) ?[*]wchar_t {
return @constCast(ptr[std.mem.findScalar(wchar_t, ptr[0..len], value) orelse return null ..]);
}
fn wmemcmp(a: [*]const wchar_t, b: [*]const wchar_t, len: usize) callconv(.c) c_int {
const idx = std.mem.findDiff(wchar_t, a[0..len], b[0..len]) orelse return 0;
return switch (std.math.order(a[idx], b[idx])) {
.eq => unreachable,
.gt => 1,
.lt => -1,
};
}
fn wmemcpy(noalias dest: [*]wchar_t, noalias src: [*]const wchar_t, len: usize) callconv(.c) [*]wchar_t {
@memcpy(dest[0..len], src[0..len]);
return dest;
}
fn wmempcpy(noalias dest: [*]wchar_t, noalias src: [*]const wchar_t, len: usize) callconv(.c) [*]wchar_t {
@memcpy(dest[0..len], src[0..len]);
return dest + len;
}
fn wmemmove(dest: [*]wchar_t, src: [*]const wchar_t, len: usize) callconv(.c) [*]wchar_t {
@memmove(dest[0..len], src[0..len]);
return dest;
}
fn wmemset(dest: [*]wchar_t, elem: wchar_t, len: usize) callconv(.c) [*]wchar_t {
@memset(dest[0..len], elem);
return dest;
}
fn wcslen(str: [*:0]const wchar_t) callconv(.c) usize {
return wcsnlen(str, std.math.maxInt(usize));
}
fn wcsnlen(str: [*:0]const wchar_t, max: usize) callconv(.c) usize {
return std.mem.findScalar(wchar_t, str[0..max], 0) orelse max;
}
fn wcscmp(a: [*:0]const wchar_t, b: [*:0]const wchar_t) callconv(.c) c_int {
return wcsncmp(a, b, std.math.maxInt(usize));
}
fn wcsncmp(a: [*:0]const wchar_t, b: [*:0]const wchar_t, max: usize) callconv(.c) c_int {
const a_slice = a[0..wcsnlen(a, max)];
const b_slice = b[0..wcsnlen(b, max)];
return switch (std.math.order(a_slice.len, b_slice.len)) {
.eq => blk: {
const idx = std.mem.findDiff(wchar_t, a_slice, b_slice) orelse break :blk 0;
break :blk switch (std.math.order(a[idx], b[idx])) {
.eq => unreachable,
.gt => 1,
.lt => -1,
};
},
.gt => 1,
.lt => -1,
};
}
fn wcpcpy(noalias dst: [*]wchar_t, noalias src: [*:0]const wchar_t) callconv(.c) [*]wchar_t {
const src_slice = std.mem.span(src);
@memcpy(dst[0..src_slice.len], src_slice);
dst[src_slice.len] = 0;
return dst + src_slice.len;
// XXX: LLVM bug?
// return wcpncpy(dst, src, std.math.maxInt(usize));
}
fn wcpncpy(noalias dst: [*]wchar_t, noalias src: [*:0]const wchar_t, max: usize) callconv(.c) [*]wchar_t {
const src_len = wcsnlen(src, max);
const copying_len = @min(max, src_len);
@memcpy(dst[0..copying_len], src[0..copying_len]);
if (copying_len < max) dst[copying_len] = 0;
return dst + copying_len;
}
fn wcscpy(noalias dst: [*]wchar_t, noalias src: [*:0]const wchar_t) callconv(.c) [*]wchar_t {
_ = wcpcpy(dst, src);
return dst;
}
fn wcsncpy(noalias dst: [*]wchar_t, noalias src: [*:0]const wchar_t, max: usize) callconv(.c) [*]wchar_t {
_ = wcpncpy(dst, src, max);
return dst;
}
fn wcscat(noalias dst: [*:0]wchar_t, noalias src: [*:0]const wchar_t) callconv(.c) [*:0]wchar_t {
return wcsncat(dst, src, std.math.maxInt(usize));
}
fn wcsncat(noalias dst: [*:0]wchar_t, noalias src: [*:0]const wchar_t, max: usize) callconv(.c) [*:0]wchar_t {
const dst_len = std.mem.len(dst);
const src_len = std.mem.len(src);
const copying_len = @min(max, src_len);
@memcpy(dst[dst_len..][0..copying_len], src[0..copying_len]);
dst[dst_len + copying_len] = 0;
return dst[0..(dst_len + copying_len) :0].ptr;
}
fn wcschr(str: [*:0]const wchar_t, value: wchar_t) callconv(.c) ?[*:0]wchar_t {
const len = std.mem.len(str);
if (value == 0) return @constCast(str + len);
return @constCast(str[std.mem.findScalar(wchar_t, str[0..len], value) orelse return null ..]);
}
fn wcsrchr(str: [*:0]const wchar_t, value: wchar_t) callconv(.c) ?[*:0]wchar_t {
// std.mem.len(str) + 1 to not special case '\0'
return @constCast(str[std.mem.findScalarLast(wchar_t, str[0..(std.mem.len(str) + 1)], value) orelse return null ..]);
}
fn wcsspn(dst: [*:0]const wchar_t, values: [*:0]const wchar_t) callconv(.c) usize {
const dst_slice = std.mem.span(dst);
return std.mem.findNone(wchar_t, dst_slice, std.mem.span(values)) orelse dst_slice.len;
}
fn wcscspn(dst: [*:0]const wchar_t, values: [*:0]const wchar_t) callconv(.c) usize {
const dst_slice = std.mem.span(dst);
return std.mem.findAny(wchar_t, dst_slice, std.mem.span(values)) orelse dst_slice.len;
}
fn wcspbrk(haystack: [*:0]const wchar_t, needle: [*:0]const wchar_t) callconv(.c) ?[*:0]wchar_t {
return @constCast(haystack[std.mem.findAny(wchar_t, std.mem.span(haystack), std.mem.span(needle)) orelse return null ..]);
}
fn wcsstr(noalias haystack: [*:0]const wchar_t, noalias needle: [*:0]const wchar_t) callconv(.c) ?[*:0]wchar_t {
return @constCast(haystack[std.mem.find(wchar_t, std.mem.span(haystack), std.mem.span(needle)) orelse return null ..]);
}
fn wcswcs(noalias haystack: [*:0]const wchar_t, noalias needle: [*:0]const wchar_t) callconv(.c) ?[*:0]wchar_t {
return wcsstr(haystack, needle);
}
-13
View File
@@ -1,13 +0,0 @@
#define __CRT__NO_INLINE
#include <string.h>
size_t __cdecl
wcsnlen(const wchar_t *w, size_t ncnt)
{
size_t n = 0;
for (; n < ncnt && *w != 0; n++, w++)
;
return n;
}
-35
View File
@@ -1,35 +0,0 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#define __CRT__NO_INLINE
#include <wchar.h>
#if 0
wchar_t *wmemchr(s, c, n)
register const wchar_t *s;
register wchar_t c;
register size_t n;
{
if ( s != NULL )
for ( ; n > 0; ++s, --n )
if ( *s == c )
return (wchar_t *)s;
return NULL;
}
#endif
_CONST_RETURN wchar_t *__cdecl wmemchr(const wchar_t *_S,wchar_t _C,size_t _N)
{
if (_S != NULL)
{
for ( ; 0 < _N; ++_S, --_N)
if (*_S == _C)
return (_CONST_RETURN wchar_t *)(_S);
}
return NULL;
}
-56
View File
@@ -1,56 +0,0 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
/* This source code was extracted from the Q8 package created and placed
in the PUBLIC DOMAIN by Doug Gwyn <gwyn@arl.mil>
last edit: 1999/11/05 gwyn@arl.mil
Implements subclause 7.24 of ISO/IEC 9899:1999 (E).
It supports an encoding where all char codes are mapped
to the *same* code values within a wchar_t or wint_t,
so long as no other wchar_t codes are used by the program.
*/
#define __CRT__NO_INLINE
#include <wchar.h>
#if 0
int
wmemcmp(s1, s2, n)
register const wchar_t *s1;
register const wchar_t *s2;
size_t n;
{
if ( n == 0 || s1 == s2 )
return 0; /* even for NULL pointers */
if ( (s1 != NULL) != (s2 != NULL) )
return s2 == NULL ? 1 : -1; /* robust */
for ( ; n > 0; ++s1, ++s2, --n )
if ( *s1 != *s2 )
return *s1 - *s2;
return 0;
}
#endif
int __cdecl wmemcmp(const wchar_t *_S1,const wchar_t *_S2,size_t _N)
{
if (_N == 0 || _S1 == _S2)
return 0; /* even for NULL pointers */
if ((_S1 != NULL) != (_S2 != NULL))
return _S2 == NULL ? 1 : -1; /* robust */
for ( ; 0 < _N; ++_S1, ++_S2, --_N)
if (*_S1 != *_S2)
return (*_S1 < *_S2 ? -1 : +1);
return 0;
}
-33
View File
@@ -1,33 +0,0 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#define __CRT__NO_INLINE
#include <wchar.h>
#if 0
wchar_t *
wmemcpy(s1, s2, n)
register wchar_t * __restrict__ s1;
register const wchar_t * __restrict__ s2;
register size_t n;
{
wchar_t *orig_s1 = s1;
if ( s1 == NULL || s2 == NULL || n == 0 )
return orig_s1; /* robust */
for ( ; n > 0; --n )
*s1++ = *s2++;
return orig_s1;
}
#endif
wchar_t *__cdecl wmemcpy(wchar_t *_S1,const wchar_t *_S2,size_t _N)
{
return (wchar_t *)memcpy(_S1,_S2,_N*sizeof(wchar_t));
}
-45
View File
@@ -1,45 +0,0 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#define __CRT__NO_INLINE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#if 0
wchar_t *
wmemmove(s1, s2, n)
register wchar_t *s1;
register const wchar_t *s2;
register size_t n;
{
wchar_t *orig_s1 = s1;
if ( s1 == NULL || s2 == NULL || n == 0 )
return orig_s1; /* robust */
/* XXX -- The following test works only within a flat address space! */
if ( s2 >= s1 )
for ( ; n > 0; --n )
*s1++ = *s2++;
else {
s1 += n;
s2 += n;
for ( ; n > 0; --n )
*--s1 = *--s2;
}
return orig_s1;
}
#endif
wchar_t *__cdecl wmemmove(wchar_t *_S1,const wchar_t *_S2,size_t _N)
{
return (wchar_t *)memmove(_S1,_S2,_N*sizeof(wchar_t));
}
-12
View File
@@ -1,12 +0,0 @@
#define __CRT__NO_INLINE
#include <wchar.h>
wchar_t * __cdecl
wmempcpy (wchar_t *d, const wchar_t *s, size_t len)
{
wchar_t *r = d + len;
if (len != 0)
memcpy (d, s, len * sizeof (wchar_t));
return r;
}
-34
View File
@@ -1,34 +0,0 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#define __CRT__NO_INLINE
#include <wchar.h>
#if 0
wchar_t *
wmemset(s, c, n)
register wchar_t *s;
register wchar_t c;
register size_t n;
{
wchar_t *orig_s = s;
if ( s != NULL )
for ( ; n > 0; --n )
*s++ = c;
return orig_s;
}
#endif
wchar_t *__cdecl wmemset(wchar_t *_S,wchar_t _C,size_t _N)
{
wchar_t *_Su = _S;
for ( ; 0 < _N; ++_Su, --_N)
*_Su = _C;
return (_S);
}
-6
View File
@@ -1,6 +0,0 @@
#include <wchar.h>
wchar_t *wcpcpy(wchar_t *restrict d, const wchar_t *restrict s)
{
return wcscpy(d, s) + wcslen(s);
}
-6
View File
@@ -1,6 +0,0 @@
#include <wchar.h>
wchar_t *wcpncpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
{
return wcsncpy(d, s, n) + wcsnlen(s, n);
}
-7
View File
@@ -1,7 +0,0 @@
#include <wchar.h>
wchar_t *wcscat(wchar_t *restrict dest, const wchar_t *restrict src)
{
wcscpy(dest + wcslen(dest), src);
return dest;
}
-8
View File
@@ -1,8 +0,0 @@
#include <wchar.h>
wchar_t *wcschr(const wchar_t *s, wchar_t c)
{
if (!c) return (wchar_t *)s + wcslen(s);
for (; *s && *s != c; s++);
return *s ? (wchar_t *)s : 0;
}
-7
View File
@@ -1,7 +0,0 @@
#include <wchar.h>
int wcscmp(const wchar_t *l, const wchar_t *r)
{
for (; *l==*r && *l && *r; l++, r++);
return *l < *r ? -1 : *l > *r;
}
-8
View File
@@ -1,8 +0,0 @@
#include <wchar.h>
wchar_t *wcscpy(wchar_t *restrict d, const wchar_t *restrict s)
{
wchar_t *a = d;
while ((*d++ = *s++));
return a;
}
-10
View File
@@ -1,10 +0,0 @@
#include <wchar.h>
size_t wcscspn(const wchar_t *s, const wchar_t *c)
{
const wchar_t *a;
if (!c[0]) return wcslen(s);
if (!c[1]) return (s=wcschr(a=s, *c)) ? s-a : wcslen(a);
for (a=s; *s && !wcschr(c, *s); s++);
return s-a;
}
-8
View File
@@ -1,8 +0,0 @@
#include <wchar.h>
size_t wcslen(const wchar_t *s)
{
const wchar_t *a;
for (a=s; *s; s++);
return s-a;
}
-10
View File
@@ -1,10 +0,0 @@
#include <wchar.h>
wchar_t *wcsncat(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
{
wchar_t *a = d;
d += wcslen(d);
while (n && *s) n--, *d++ = *s++;
*d++ = 0;
return a;
}
-7
View File
@@ -1,7 +0,0 @@
#include <wchar.h>
int wcsncmp(const wchar_t *l, const wchar_t *r, size_t n)
{
for (; n && *l==*r && *l && *r; n--, l++, r++);
return n ? (*l < *r ? -1 : *l > *r) : 0;
}
-9
View File
@@ -1,9 +0,0 @@
#include <wchar.h>
wchar_t *wcsncpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
{
wchar_t *a = d;
while (n && *s) n--, *d++ = *s++;
wmemset(d, 0, n);
return a;
}
-8
View File
@@ -1,8 +0,0 @@
#include <wchar.h>
size_t wcsnlen(const wchar_t *s, size_t n)
{
const wchar_t *z = wmemchr(s, 0, n);
if (z) n = z-s;
return n;
}
-7
View File
@@ -1,7 +0,0 @@
#include <wchar.h>
wchar_t *wcspbrk(const wchar_t *s, const wchar_t *b)
{
s += wcscspn(s, b);
return *s ? (wchar_t *)s : NULL;
}
-8
View File
@@ -1,8 +0,0 @@
#include <wchar.h>
wchar_t *wcsrchr(const wchar_t *s, wchar_t c)
{
const wchar_t *p;
for (p=s+wcslen(s); p>=s && *p!=c; p--);
return p>=s ? (wchar_t *)p : 0;
}
-8
View File
@@ -1,8 +0,0 @@
#include <wchar.h>
size_t wcsspn(const wchar_t *s, const wchar_t *c)
{
const wchar_t *a;
for (a=s; *s && wcschr(c, *s); s++);
return s-a;
}
-105
View File
@@ -1,105 +0,0 @@
#include <wchar.h>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
static wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n)
{
const wchar_t *z;
size_t l, ip, jp, k, p, ms, p0, mem, mem0;
/* Computing length of needle */
for (l=0; n[l] && h[l]; l++);
if (n[l]) return 0; /* hit the end of h */
/* Compute maximal suffix */
ip = -1; jp = 0; k = p = 1;
while (jp+k<l) {
if (n[ip+k] == n[jp+k]) {
if (k == p) {
jp += p;
k = 1;
} else k++;
} else if (n[ip+k] > n[jp+k]) {
jp += k;
k = 1;
p = jp - ip;
} else {
ip = jp++;
k = p = 1;
}
}
ms = ip;
p0 = p;
/* And with the opposite comparison */
ip = -1; jp = 0; k = p = 1;
while (jp+k<l) {
if (n[ip+k] == n[jp+k]) {
if (k == p) {
jp += p;
k = 1;
} else k++;
} else if (n[ip+k] < n[jp+k]) {
jp += k;
k = 1;
p = jp - ip;
} else {
ip = jp++;
k = p = 1;
}
}
if (ip+1 > ms+1) ms = ip;
else p = p0;
/* Periodic needle? */
if (wmemcmp(n, n+p, ms+1)) {
mem0 = 0;
p = MAX(ms, l-ms-1) + 1;
} else mem0 = l-p;
mem = 0;
/* Initialize incremental end-of-haystack pointer */
z = h;
/* Search loop */
for (;;) {
/* Update incremental end-of-haystack pointer */
if (z-h < l) {
/* Fast estimate for MIN(l,63) */
size_t grow = l | 63;
const wchar_t *z2 = wmemchr(z, 0, grow);
if (z2) {
z = z2;
if (z-h < l) return 0;
} else z += grow;
}
/* Compare right half */
for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
if (n[k]) {
h += k-ms;
mem = 0;
continue;
}
/* Compare left half */
for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
if (k <= mem) return (wchar_t *)h;
h += p;
mem = mem0;
}
}
wchar_t *wcsstr(const wchar_t *restrict h, const wchar_t *restrict n)
{
/* Return immediately on empty needle or haystack */
if (!n[0]) return (wchar_t *)h;
if (!h[0]) return 0;
/* Use faster algorithms for short needles */
h = wcschr(h, *n);
if (!h || !n[1]) return (wchar_t *)h;
if (!h[1]) return 0;
return twoway_wcsstr(h, n);
}
-6
View File
@@ -1,6 +0,0 @@
#include <wchar.h>
wchar_t *wcswcs(const wchar_t *haystack, const wchar_t *needle)
{
return wcsstr(haystack, needle);
}
-7
View File
@@ -1,7 +0,0 @@
#include <wchar.h>
wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)
{
for (; n && *s != c; n--, s++);
return n ? (wchar_t *)s : 0;
}
-7
View File
@@ -1,7 +0,0 @@
#include <wchar.h>
int wmemcmp(const wchar_t *l, const wchar_t *r, size_t n)
{
for (; n && *l==*r; n--, l++, r++);
return n ? (*l < *r ? -1 : *l > *r) : 0;
}
-8
View File
@@ -1,8 +0,0 @@
#include <wchar.h>
wchar_t *wmemcpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
{
wchar_t *a = d;
while (n--) *d++ = *s++;
return a;
}
-13
View File
@@ -1,13 +0,0 @@
#include <wchar.h>
#include <stdint.h>
wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n)
{
wchar_t *d0 = d;
if (d == s) return d;
if ((uintptr_t)d-(uintptr_t)s < n * sizeof *d)
while (n--) d[n] = s[n];
else
while (n--) *d++ = *s++;
return d0;
}
-8
View File
@@ -1,8 +0,0 @@
#include <wchar.h>
wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n)
{
wchar_t *ret = d;
while (n--) *d++ = c;
return ret;
}
+10
View File
@@ -11067,6 +11067,16 @@ pub const imaxdiv_t = extern struct {
pub const intmax_t = i64;
pub const uintmax_t = u64;
pub const wint_t = switch (builtin.target.os.tag) {
.windows => u16,
else => i32,
};
pub const wchar_t = switch (builtin.target.os.tag) {
.windows => u16,
else => if (builtin.target.cpu.arch.isArm() or builtin.target.cpu.arch.isAARCH64()) u32 else i32,
};
pub extern "c" fn pthread_getthreadid_np() c_int;
pub extern "c" fn pthread_set_name_np(thread: pthread_t, name: [*:0]const u8) void;
pub extern "c" fn pthread_get_name_np(thread: pthread_t, name: [*:0]u8, len: usize) void;
-7
View File
@@ -681,7 +681,6 @@ const mingw32_generic_src = [_][]const u8{
"misc" ++ path.sep_str ++ "tfind.c",
"misc" ++ path.sep_str ++ "tsearch.c",
"misc" ++ path.sep_str ++ "twalk.c",
"misc" ++ path.sep_str ++ "wcsnlen.c",
"misc" ++ path.sep_str ++ "wcstof.c",
"misc" ++ path.sep_str ++ "wcstoimax.c",
"misc" ++ path.sep_str ++ "wcstold.c",
@@ -691,12 +690,6 @@ const mingw32_generic_src = [_][]const u8{
"misc" ++ path.sep_str ++ "winbs_uint64.c",
"misc" ++ path.sep_str ++ "winbs_ulong.c",
"misc" ++ path.sep_str ++ "winbs_ushort.c",
"misc" ++ path.sep_str ++ "wmemchr.c",
"misc" ++ path.sep_str ++ "wmemcmp.c",
"misc" ++ path.sep_str ++ "wmemcpy.c",
"misc" ++ path.sep_str ++ "wmemmove.c",
"misc" ++ path.sep_str ++ "wmempcpy.c",
"misc" ++ path.sep_str ++ "wmemset.c",
"stdio" ++ path.sep_str ++ "_Exit.c",
"stdio" ++ path.sep_str ++ "_findfirst64i32.c",
"stdio" ++ path.sep_str ++ "_findnext64i32.c",
-22
View File
@@ -1651,34 +1651,12 @@ const src_files = [_][]const u8{
"musl/src/string/strtok_r.c",
"musl/src/string/strverscmp.c",
"musl/src/string/swab.c",
"musl/src/string/wcpcpy.c",
"musl/src/string/wcpncpy.c",
"musl/src/string/wcscasecmp.c",
"musl/src/string/wcscasecmp_l.c",
"musl/src/string/wcscat.c",
"musl/src/string/wcschr.c",
"musl/src/string/wcscmp.c",
"musl/src/string/wcscpy.c",
"musl/src/string/wcscspn.c",
"musl/src/string/wcsdup.c",
"musl/src/string/wcslen.c",
"musl/src/string/wcsncasecmp.c",
"musl/src/string/wcsncasecmp_l.c",
"musl/src/string/wcsncat.c",
"musl/src/string/wcsncmp.c",
"musl/src/string/wcsncpy.c",
"musl/src/string/wcsnlen.c",
"musl/src/string/wcspbrk.c",
"musl/src/string/wcsrchr.c",
"musl/src/string/wcsspn.c",
"musl/src/string/wcsstr.c",
"musl/src/string/wcstok.c",
"musl/src/string/wcswcs.c",
"musl/src/string/wmemchr.c",
"musl/src/string/wmemcmp.c",
"musl/src/string/wmemcpy.c",
"musl/src/string/wmemmove.c",
"musl/src/string/wmemset.c",
"musl/src/temp/mkdtemp.c",
"musl/src/temp/mkostemp.c",
"musl/src/temp/mkostemps.c",
-22
View File
@@ -999,34 +999,12 @@ const libc_top_half_src_files = [_][]const u8{
"musl/src/string/strtok_r.c",
"musl/src/string/strverscmp.c",
"musl/src/string/swab.c",
"musl/src/string/wcpcpy.c",
"musl/src/string/wcpncpy.c",
"musl/src/string/wcscasecmp.c",
"musl/src/string/wcscasecmp_l.c",
"musl/src/string/wcscat.c",
"musl/src/string/wcschr.c",
"musl/src/string/wcscmp.c",
"musl/src/string/wcscpy.c",
"musl/src/string/wcscspn.c",
"musl/src/string/wcsdup.c",
"musl/src/string/wcslen.c",
"musl/src/string/wcsncasecmp.c",
"musl/src/string/wcsncasecmp_l.c",
"musl/src/string/wcsncat.c",
"musl/src/string/wcsncmp.c",
"musl/src/string/wcsncpy.c",
"musl/src/string/wcsnlen.c",
"musl/src/string/wcspbrk.c",
"musl/src/string/wcsrchr.c",
"musl/src/string/wcsspn.c",
"musl/src/string/wcsstr.c",
"musl/src/string/wcstok.c",
"musl/src/string/wcswcs.c",
"musl/src/string/wmemchr.c",
"musl/src/string/wmemcmp.c",
"musl/src/string/wmemcpy.c",
"musl/src/string/wmemmove.c",
"musl/src/string/wmemset.c",
"musl/src/thread/default_attr.c",
"musl/src/thread/pthread_attr_destroy.c",
"musl/src/thread/pthread_attr_init.c",