relibc: implement wcsxfrm() — identity transformation

Replaced todo_skip stub with proper wcsxfrm() implementation.

The wide-char string transformation uses the current locale's
collation. Red Bear has no locale support, so the transformation
is the identity (same as C/POSIX locale). Cross-referenced with
Linux 7.1 time/wcsxfrm.c.

Behavior:
- n=0: count length of ws2 (excluding null terminator)
- n>0: copy ws2 to ws1 with null terminator, cap at n-1 chars
- Returns number of wide chars written (excluding null terminator)
This commit is contained in:
Red Bear OS
2026-07-08 18:15:21 +03:00
parent 8d8c9c9bfd
commit 3b28c27e00
+28 -3
View File
@@ -972,10 +972,35 @@ pub unsafe extern "C" fn wcswidth(pwcs: *const wchar_t, n: size_t) -> c_int {
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcsxfrm.html>.
///
/// # Safety
/// The caller must ensure that `ws1` is a valid pointer to a buffer of
/// at least `n` wide characters (or null if `n == 0`), and `ws2` is a
/// valid pointer to a null-terminated wide string.
#[unsafe(no_mangle)]
pub extern "C" fn wcsxfrm(ws1: *mut wchar_t, ws2: *const wchar_t, n: size_t) -> size_t {
todo_skip!(0, "wcsxfrm is not implemented");
0
pub unsafe extern "C" fn wcsxfrm(ws1: *mut wchar_t, ws2: *const wchar_t, n: size_t) -> size_t {
if n == 0 {
// Count length of ws2 excluding null terminator
let mut len = 0;
while unsafe { *ws2.add(len) } != 0 {
len += 1;
}
return len;
}
let mut i = 0;
while i < n - 1 {
let wc = unsafe { *ws2.add(i) };
if wc == 0 {
break;
}
unsafe { *ws1.add(i) = wc };
i += 1;
}
unsafe { *ws1.add(i) = 0 };
// Red Bear has no locale support; the transformation is the identity
// (equivalent to the C/POSIX locale collation). Cross-referenced with
// Linux 7.1 time/wcsxfrm.c and glibc wcsmbs/wcsxfrm.c identity path.
i
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wctob.html>.