Add wcpcpy, wcpncpy, wcsdup, wcsnlen, wcsnrtombs

This commit is contained in:
Darley Barreto
2023-10-19 14:58:37 +00:00
committed by Jeremy Soller
parent 2c7ec0dc8e
commit 05992b8451
17 changed files with 172 additions and 2 deletions
+93 -2
View File
@@ -4,8 +4,8 @@ use core::{char, ffi::VaList as va_list, mem, ptr, slice, usize};
use crate::{
header::{
ctype::isspace, errno::{ERANGE, EILSEQ}, stdio::*,
stdlib::MB_CUR_MAX, string, time::*, wctype::*,
ctype::isspace, errno::{ERANGE, EILSEQ, ENOMEM}, stdio::*,
stdlib::{MB_CUR_MAX, MB_LEN_MAX, malloc}, string, time::*, wctype::*,
},
platform::{self, errno, types::*},
};
@@ -319,6 +319,23 @@ pub unsafe extern "C" fn vswprintf(
-1
}
#[no_mangle]
pub unsafe extern "C" fn wcpcpy(
d: *mut wchar_t,
s: *const wchar_t,
) -> *mut wchar_t {
return (wcscpy(d, s)).offset(wcslen(s) as isize);
}
#[no_mangle]
pub unsafe extern "C" fn wcpncpy(
d: *mut wchar_t,
s: *const wchar_t,
n: size_t,
) -> *mut wchar_t {
return (wcsncpy(d, s, n)).offset(wcsnlen(s, n) as isize);
}
//widechar to multibyte
#[no_mangle]
pub unsafe extern "C" fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t) -> size_t {
@@ -332,6 +349,20 @@ 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 wcsdup(s: *const wchar_t) -> *mut wchar_t {
let l = wcslen(s);
let mut d = malloc((l + 1)*mem::size_of::<wchar_t>()) as *mut wchar_t;
if d.is_null() {
errno = ENOMEM;
return ptr::null_mut();
}
wmemcpy(d, s, l + 1)
}
#[no_mangle]
pub unsafe extern "C" fn wcsrtombs(
mut s: *mut c_char,
@@ -550,6 +581,66 @@ pub unsafe extern "C" fn wcsncpy(
ws1
}
#[no_mangle]
pub unsafe extern "C" fn wcsnlen(mut s: *const wchar_t, maxlen: size_t) -> size_t {
let mut len = 0;
while len < maxlen {
if *s == 0 {
break;
}
len = len + 1;
s = s.offset(1);
}
return len;
}
#[no_mangle]
pub unsafe extern "C" fn wcsnrtombs(
mut dest: *mut c_char,
src: *mut *const wchar_t,
nwc: size_t,
len: size_t,
ps: *mut mbstate_t,
) -> size_t {
let mut written = 0;
let mut read = 0;
let mut buf: [c_char; MB_LEN_MAX as usize] = [0; MB_LEN_MAX as usize];
while read < nwc {
buf.fill(0);
let ret = wcrtomb(buf.as_mut_ptr(), **src, ps);
if ret == size_t::MAX {
errno = EILSEQ;
return size_t::MAX;
}
if !dest.is_null() && len < written + ret {
return written;
}
if !dest.is_null() {
ptr::copy_nonoverlapping(buf.as_ptr(), dest, ret);
dest = dest.add(ret);
}
if **src == '\0' as wchar_t {
*src = ptr::null();
return written;
}
*src = (*src).add(1);
read += 1;
written += ret;
}
written
}
#[no_mangle]
pub unsafe extern "C" fn wcspbrk(mut wcs: *const wchar_t, set: *const wchar_t) -> *mut wchar_t {
wcs = wcs.add(wcscspn(wcs, set));
+5
View File
@@ -111,7 +111,10 @@ EXPECT_NAMES=\
wchar/ungetwc \
wchar/wprintf \
wchar/wcrtomb \
wchar/wcpcpy \
wchar/wcpncpy \
wchar/wcscspn \
wchar/wcsdup \
wchar/wcsrchr \
wchar/wcsrtombs \
wchar/wcsstr \
@@ -122,6 +125,8 @@ EXPECT_NAMES=\
wchar/wcstoumax \
wchar/wcscasecmp \
wchar/wcsncasecmp \
wchar/wcsnlen \
wchar/wcsnrtombs \
wchar/wcswidth \
wctype/towlower \
wctype/towupper
+16
View File
@@ -0,0 +1,16 @@
#include <wchar.h>
#include <assert.h>
#include <string.h>
int main() {
wchar_t src[] = L"こんにちは世界!";
wchar_t dest[9];
wchar_t* result = wcpcpy(dest, src);
assert(wcscmp(dest, src) == 0);
assert(*result == L'\0');
assert(result == dest + wcslen(src));
return 0;
}
+15
View File
@@ -0,0 +1,15 @@
#include <wchar.h>
#include <assert.h>
#include <string.h>
int main() {
wchar_t src[] = L"Привет мир";
wchar_t dest[10];
wchar_t* result = wcpncpy(dest, src, 5);
assert(wcsncmp(dest, src, 5) == 0);
assert(*result == L'\0');
assert(result == dest + 5);
return 0;
}
+16
View File
@@ -0,0 +1,16 @@
#include <wchar.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
int main() {
wchar_t src[] = L"こんにちは世界Привет мир";
wchar_t* dup = wcsdup(src);
assert(wcscmp(dup, src) == 0);
assert(dup != src);
free(dup);
return 0;
}
+9
View File
@@ -0,0 +1,9 @@
#include <wchar.h>
#include <assert.h>
int main() {
// size is 17
wchar_t* str1 = L"こんにちは世界Привет мир";
assert(wcsnlen(str1, 10) == 10);
assert(wcsnlen(str1, 100) == 17);
}
+18
View File
@@ -0,0 +1,18 @@
#include <assert.h>
#include <locale.h>
#include <wchar.h>
#include <string.h>
int main() {
setlocale(LC_ALL, "");
const wchar_t *src = L"こんにちは世界Привет мир";
char dst[20];
mbstate_t ps;
size_t result = wcsnrtombs(dst, &src, 4, sizeof(dst), &ps);
assert(result == 12);
assert(strcmp(dst, "こんにち") == 0);
return 0;
}