Adding wcsrtombs.
This commit is contained in:
committed by
Jeremy Soller
parent
26a8e316f1
commit
7155005be2
@@ -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
@@ -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)
|
||||
|
||||
@@ -110,6 +110,7 @@ EXPECT_NAMES=\
|
||||
wchar/wcrtomb \
|
||||
wchar/wcscspn \
|
||||
wchar/wcsrchr \
|
||||
wchar/wcsrtombs \
|
||||
wchar/wcsstr \
|
||||
wchar/wcstod \
|
||||
wchar/wcstok \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user