diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs index 465e05ac93..e91c2e0f33 100644 --- a/src/header/wchar/mod.rs +++ b/src/header/wchar/mod.rs @@ -972,10 +972,35 @@ pub unsafe extern "C" fn wcswidth(pwcs: *const wchar_t, n: size_t) -> c_int { } /// See . +/// +/// # 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 .