libc: implement wcrtomb()
This commit is contained in:
parent
cd22da9098
commit
d2a31ef99b
@ -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::<u8>().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]
|
||||
|
Loading…
x
Reference in New Issue
Block a user