diff --git a/userspace/lib/ygglibc/src/headers/wchar/multibyte.rs b/userspace/lib/ygglibc/src/headers/wchar/multibyte.rs index 69241815..350adb79 100644 --- a/userspace/lib/ygglibc/src/headers/wchar/multibyte.rs +++ b/userspace/lib/ygglibc/src/headers/wchar/multibyte.rs @@ -1,20 +1,41 @@ -use core::{ffi::{c_char, c_int}, ptr::NonNull}; +use core::{ + ffi::{c_char, c_int}, + ptr::NonNull, +}; -use crate::{error::CUsizeResult, headers::wchar::imp, types::wchar_t}; +use crate::{ + error::{CIntZeroResult, CUsizeResult, OptionExt}, + headers::{errno::Errno, stdlib::MB_CUR_MAX, wchar::imp}, + types::wchar_t, + util::PointerExt, +}; use super::mbstate_t; +static mut GLOBAL: mbstate_t = mbstate_t { __dummy: 0 }; + #[no_mangle] unsafe extern "C" fn mbrlen(_str: *const c_char, _n: usize, _state: *mut mbstate_t) -> usize { todo!() } #[no_mangle] -unsafe extern "C" fn wcrtomb(_dst: *mut c_char, _wc: wchar_t, _state: *mut mbstate_t) -> usize { - todo!() +unsafe extern "C" fn wcrtomb(dst: *mut c_char, wc: wchar_t, state: *mut mbstate_t) -> CUsizeResult { + let state = match state.as_mut() { + Some(state) => state, + #[allow(static_mut_refs)] + None => &mut GLOBAL, + }; + // dst must be at least MB_CUR_MAX (4) + let dst = dst.cast::().ensure_slice_mut(MB_CUR_MAX as usize); + + // TODO EILSEQ + let ch = char::from_u32(wc as u32).e_ok_or(Errno::EINVAL)?; + + let len = ch.encode_utf8(dst).len(); + CUsizeResult::success(len) } -#[allow(static_mut_refs)] #[no_mangle] pub unsafe extern "C" fn mbrtowc( dst: *mut wchar_t, @@ -22,17 +43,14 @@ pub unsafe extern "C" fn mbrtowc( n: usize, state: *mut mbstate_t, ) -> CUsizeResult { - static mut GLOBAL: mbstate_t = mbstate_t { __dummy: 0 }; - let state = match state.as_mut() { Some(state) => state, - None => &mut GLOBAL + #[allow(static_mut_refs)] + None => &mut GLOBAL, }; let res = match NonNull::new(src.cast_mut()) { - Some(src) => { - imp::mbrtowc(dst, src, n, state)? - } + Some(src) => imp::mbrtowc(dst, src, n, state)?, None => { let x: [c_char; 1] = [0]; imp::mbrtowc(dst, NonNull::from_ref(&x[0]), 1, state)? @@ -43,8 +61,8 @@ pub unsafe extern "C" fn mbrtowc( } #[no_mangle] -unsafe extern "C" fn mbsinit(_state: *const mbstate_t) -> c_int { - todo!() +unsafe extern "C" fn mbsinit(_state: *const mbstate_t) -> CIntZeroResult { + CIntZeroResult::SUCCESS } #[no_mangle]