From 9642d2ab027f4f07494d8a63c44cb7ec318df0fc Mon Sep 17 00:00:00 2001 From: Darley Barreto <darleybarreto@gmail.com> Date: Mon, 22 May 2023 16:01:04 +0000 Subject: [PATCH] Adding some wcst* functions --- src/header/inttypes/mod.rs | 24 +----- src/header/wchar/mod.rs | 76 ++++++++++++++++++- tests/Makefile | 2 + .../bins_static/wchar/wcstoimax.stderr | 0 .../bins_static/wchar/wcstoimax.stdout | 6 ++ .../expected/bins_static/wchar/wcstol.stdout | 2 +- .../bins_static/wchar/wcstoumax.stderr | 0 .../bins_static/wchar/wcstoumax.stdout | 3 + tests/wchar/wcstoimax.c | 13 ++++ tests/wchar/wcstoumax.c | 15 ++++ 10 files changed, 116 insertions(+), 25 deletions(-) create mode 100644 tests/expected/bins_static/wchar/wcstoimax.stderr create mode 100644 tests/expected/bins_static/wchar/wcstoimax.stdout create mode 100644 tests/expected/bins_static/wchar/wcstoumax.stderr create mode 100644 tests/expected/bins_static/wchar/wcstoumax.stdout create mode 100644 tests/wchar/wcstoimax.c create mode 100644 tests/wchar/wcstoumax.c diff --git a/src/header/inttypes/mod.rs b/src/header/inttypes/mod.rs index 52ec258c7..089ac5e7c 100644 --- a/src/header/inttypes/mod.rs +++ b/src/header/inttypes/mod.rs @@ -1,5 +1,7 @@ +use core::{convert::TryInto, ptr}; + use crate::{ - header::{ctype, errno::*, stdlib::*}, + header::{ctype, errno::*, stdlib::*, wctype::iswspace}, platform::{self, types::*}, }; @@ -56,23 +58,3 @@ pub unsafe extern "C" fn strtoumax( base ) } - -#[allow(unused)] -// #[no_mangle] -pub extern "C" fn wcstoimax( - nptr: *const wchar_t, - endptr: *mut *mut wchar_t, - base: c_int, -) -> intmax_t { - unimplemented!(); -} - -#[allow(unused)] -// #[no_mangle] -pub extern "C" fn wcstoumax( - nptr: *const wchar_t, - endptr: *mut *mut wchar_t, - base: c_int, -) -> uintmax_t { - unimplemented!(); -} diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs index cc8eb4f7b..28bbb1093 100644 --- a/src/header/wchar/mod.rs +++ b/src/header/wchar/mod.rs @@ -660,14 +660,28 @@ macro_rules! strtou_impl { strtou_impl!($type, $ptr, $base, false) }; ($type:ident, $ptr:expr, $base:expr, $negative:expr) => {{ - if $base == 16 && *$ptr == '0' as wchar_t && *$ptr.add(1) | 0x20 == 'x' as wchar_t { + let mut base = $base; + + if (base == 16 || base == 0) + && *$ptr == '0' as wchar_t + && (*$ptr.add(1) == 'x' as wchar_t || *$ptr.add(1) == 'X' as wchar_t) + { $ptr = $ptr.add(2); + base = 16; } + + if base == 0 { + base = if *$ptr == '0' as wchar_t { + 8 + } else { + 10 + }; + }; let mut result: $type = 0; - while let Some(digit) = char::from_u32(*$ptr as u32).and_then(|c| c.to_digit($base as u32)) + while let Some(digit) = char::from_u32(*$ptr as u32).and_then(|c| c.to_digit(base as u32)) { - let new = result.checked_mul($base as $type).and_then(|result| { + let new = result.checked_mul(base as $type).and_then(|result| { if $negative { result.checked_sub(digit as $type) } else { @@ -711,6 +725,34 @@ pub unsafe extern "C" fn wcstol( result } +#[no_mangle] +pub unsafe extern "C" fn wcstoll( + mut ptr: *const wchar_t, + end: *mut *mut wchar_t, + base: c_int, +) -> c_longlong { + skipws!(ptr); + let result = strto_impl!(c_longlong, ptr, base); + if !end.is_null() { + *end = ptr as *mut _; + } + result +} + +#[no_mangle] +pub unsafe extern "C" fn wcstoimax( + mut ptr: *const wchar_t, + end: *mut *mut wchar_t, + base: c_int, +) -> intmax_t { + skipws!(ptr); + let result = strto_impl!(intmax_t, ptr, base); + if !end.is_null() { + *end = ptr as *mut _; + } + result +} + #[no_mangle] pub unsafe extern "C" fn wcstoul( mut ptr: *const wchar_t, @@ -725,6 +767,34 @@ pub unsafe extern "C" fn wcstoul( result } +#[no_mangle] +pub unsafe extern "C" fn wcstoull( + mut ptr: *const wchar_t, + end: *mut *mut wchar_t, + base: c_int, +) -> c_ulonglong { + skipws!(ptr); + let result = strtou_impl!(c_ulonglong, ptr, base); + if !end.is_null() { + *end = ptr as *mut _; + } + result +} + +#[no_mangle] +pub unsafe extern "C" fn wcstoumax( + mut ptr: *const wchar_t, + end: *mut *mut wchar_t, + base: c_int, +) -> uintmax_t { + skipws!(ptr); + let result = strtou_impl!(uintmax_t, ptr, base); + if !end.is_null() { + *end = ptr as *mut _; + } + result +} + // #[no_mangle] pub extern "C" fn wcswcs(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar_t { unimplemented!(); diff --git a/tests/Makefile b/tests/Makefile index bf1a04aa2..f6ccb321d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -117,6 +117,8 @@ EXPECT_NAMES=\ wchar/wcstod \ wchar/wcstok \ wchar/wcstol \ + wchar/wcstoimax \ + wchar/wcstoumax \ wchar/wcscasecmp \ wchar/wcsncasecmp \ wchar/wcswidth \ diff --git a/tests/expected/bins_static/wchar/wcstoimax.stderr b/tests/expected/bins_static/wchar/wcstoimax.stderr new file mode 100644 index 000000000..e69de29bb diff --git a/tests/expected/bins_static/wchar/wcstoimax.stdout b/tests/expected/bins_static/wchar/wcstoimax.stdout new file mode 100644 index 000000000..b9a14be84 --- /dev/null +++ b/tests/expected/bins_static/wchar/wcstoimax.stdout @@ -0,0 +1,6 @@ +-123 +255 +44027 +8 +10 +16 diff --git a/tests/expected/bins_static/wchar/wcstol.stdout b/tests/expected/bins_static/wchar/wcstol.stdout index ec5ae5877..55aa50779 100644 --- a/tests/expected/bins_static/wchar/wcstol.stdout +++ b/tests/expected/bins_static/wchar/wcstol.stdout @@ -1 +1 @@ -The decimal equivalents are: 2001, 6340800, -3624224 and 0. +The decimal equivalents are: 2001, 6340800, -3624224 and 7340031. diff --git a/tests/expected/bins_static/wchar/wcstoumax.stderr b/tests/expected/bins_static/wchar/wcstoumax.stderr new file mode 100644 index 000000000..e69de29bb diff --git a/tests/expected/bins_static/wchar/wcstoumax.stdout b/tests/expected/bins_static/wchar/wcstoumax.stdout new file mode 100644 index 000000000..8e372f758 --- /dev/null +++ b/tests/expected/bins_static/wchar/wcstoumax.stdout @@ -0,0 +1,3 @@ +nptr = `10110134932` +wcstoumax = 10110134932 +Stopped scan at `` diff --git a/tests/wchar/wcstoimax.c b/tests/wchar/wcstoimax.c new file mode 100644 index 000000000..546314d06 --- /dev/null +++ b/tests/wchar/wcstoimax.c @@ -0,0 +1,13 @@ +#include <inttypes.h> +#include <stdio.h> +#include <wchar.h> + +int main(void) { + wchar_t* endptr; + wprintf(L"%ld\n", wcstoimax(L" -123junk", &endptr, 10)); /* base 10 */ + wprintf(L"%ld\n", wcstoimax(L"11111111", &endptr, 2)); /* base 2 */ + wprintf(L"%ld\n", wcstoimax(L"XyZ", &endptr, 36)); /* base 36 */ + wprintf(L"%ld\n", wcstoimax(L"010", &endptr, 0)); /* octal auto-detection */ + wprintf(L"%ld\n", wcstoimax(L"10", &endptr, 0)); /* decimal auto-detection */ + wprintf(L"%ld\n", wcstoimax(L"0x10", &endptr, 0)); /* hexadecimal auto-detection */ +} \ No newline at end of file diff --git a/tests/wchar/wcstoumax.c b/tests/wchar/wcstoumax.c new file mode 100644 index 000000000..8f4c80b8a --- /dev/null +++ b/tests/wchar/wcstoumax.c @@ -0,0 +1,15 @@ +#include <inttypes.h> +#include <stdio.h> +#include <wchar.h> + +int main(void) { + wchar_t *nptr; + wchar_t *endptr; + uintmax_t j; + int base = 10; + nptr = L"10110134932"; + printf("nptr = `%ls`\n", nptr); + j = wcstoumax(nptr, &endptr, base); + printf("wcstoumax = %ju\n", j); + printf("Stopped scan at `%ls`\n", endptr); +} \ No newline at end of file -- GitLab