Adding wcsrtombs.

This commit is contained in:
Darley Barreto
2023-05-08 12:39:53 +00:00
committed by Jeremy Soller
parent 26a8e316f1
commit 7155005be2
4 changed files with 102 additions and 11 deletions
+1 -1
View File
@@ -1266,7 +1266,7 @@ pub unsafe extern "C" fn valloc(size: size_t) -> *mut c_void {
}
#[no_mangle]
pub extern "C" fn wcstombs(s: *mut c_char, mut pwcs: *const wchar_t, n: size_t) -> size_t {
pub unsafe extern "C" fn wcstombs(s: *mut c_char, mut pwcs: *const wchar_t, n: size_t) -> size_t {
let mut state: mbstate_t = mbstate_t {};
wcsrtombs(s, &mut pwcs, n, &mut state)
}
+79 -10
View File
@@ -275,6 +275,85 @@ pub unsafe extern "C" fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t
utf8::wcrtomb(s_cpy, wc_cpy, ps)
}
#[no_mangle]
pub unsafe extern "C" fn wcsrtombs(
mut s: *mut c_char,
ws: *mut *const wchar_t,
mut n: size_t,
st: *mut mbstate_t,
) -> size_t {
let mut ws2 = 0 as *const wchar_t;
let mut buf = [0i8; 4];
let N = n;
let mut l = 0usize;
if s.is_null() {
n = 0;
ws2 = *ws;
while *ws2 != 0 {
if *ws2 >= 0x80 {
l = wcrtomb(buf.as_mut_ptr(), *ws2, ptr::null_mut());
if l.wrapping_add(1) == 0 {
return usize::MAX;
}
n = n.wrapping_add(l);
} else {
n = n.wrapping_add(1);
}
ws2 = ws2.offset(1);
}
return n;
}
while n >= 4 {
if **ws.wrapping_sub(1) >= 0x7f {
if **ws == 0 {
*s = 0;
*ws = 0 as *const wchar_t;
return N.wrapping_sub(n);
}
l = wcrtomb(s, **ws, ptr::null_mut());
if l.wrapping_add(1) == 0 {
return usize::MAX;
}
s = s.offset(l as isize);
n = n.wrapping_sub(l);
} else {
let new_s = s;
s = s.offset(1);
*new_s = **ws as c_char;
n = n.wrapping_sub(1);
}
*ws = (*ws).offset(1);
}
while n != 0 {
if **ws.wrapping_sub(1) >= 0x7f {
if **ws == 0 {
*s = 0;
*ws = 0 as *const wchar_t;
return N.wrapping_sub(n);
}
l = wcrtomb(buf.as_mut_ptr(), **ws, ptr::null_mut());
if l.wrapping_add(1) == 0 {
return usize::MAX;
}
if l > n {
return N.wrapping_sub(n);
}
wcrtomb(s, **ws, ptr::null_mut());
s = s.offset(l as isize);
n = n.wrapping_sub(l) as size_t;
} else {
let new_s = s;
s = s.offset(1);
*new_s = **ws as c_char;
n = n.wrapping_sub(1);
}
*ws = (*ws).offset(1);
}
return N;
}
#[no_mangle]
pub unsafe extern "C" fn wcscat(ws1: *mut wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
wcsncat(ws1, ws2, usize::MAX)
@@ -436,16 +515,6 @@ pub unsafe extern "C" fn wcsrchr(ws1: *const wchar_t, wc: wchar_t) -> *mut wchar
last_matching_wc as *mut wchar_t
}
// #[no_mangle]
pub extern "C" fn wcsrtombs(
dst: *mut c_char,
src: *mut *const wchar_t,
len: size_t,
ps: *mut mbstate_t,
) -> size_t {
unimplemented!();
}
#[no_mangle]
pub unsafe extern "C" fn wcsspn(wcs: *const wchar_t, set: *const wchar_t) -> size_t {
inner_wcsspn(wcs, set, false)
+1
View File
@@ -110,6 +110,7 @@ EXPECT_NAMES=\
wchar/wcrtomb \
wchar/wcscspn \
wchar/wcsrchr \
wchar/wcsrtombs \
wchar/wcsstr \
wchar/wcstod \
wchar/wcstok \
+21
View File
@@ -0,0 +1,21 @@
#include <assert.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
int main() {
const wchar_t *wcs1 = L"";
size_t mb_len1 = wcsrtombs(NULL, &wcs1, 0, NULL);
assert(mb_len1 == 0);
const wchar_t *wcs2 = L"Hello, world!";
size_t mb_len2 = wcsrtombs(NULL, &wcs2, 0, NULL);
assert(mb_len2 == strlen("Hello, world!"));
char *mbs2 = malloc(mb_len2 + 1);
wcsrtombs(mbs2, &wcs2, mb_len2 + 1, NULL);
assert(strcmp(mbs2, "Hello, world!") == 0);
free(mbs2);
return 0;
}