diff --git a/src/header/inttypes/mod.rs b/src/header/inttypes/mod.rs index 52ec258c701d742e4984647a74d3fc006f83cd2d..089ac5e7c9e4905c0974adbafaf252b8f439bf49 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 cc8eb4f7bf62adaeba68e41d7137c53a2e938a3a..28bbb1093c21f822a7989b62395daa0b997555d9 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 bf1a04aa26ffae11ab6a62e8b240c441e16bf09a..f6ccb321d4c335710e7f98f37f28fa820f5bf8b5 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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/expected/bins_static/wchar/wcstoimax.stdout b/tests/expected/bins_static/wchar/wcstoimax.stdout new file mode 100644 index 0000000000000000000000000000000000000000..b9a14be845f22081edd1caff314384bf6e675a2c --- /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 ec5ae58779e228b581f35469ad8f5313e1181f19..55aa50779a55a1626e92d9f7f86eda6e956dc7de 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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/expected/bins_static/wchar/wcstoumax.stdout b/tests/expected/bins_static/wchar/wcstoumax.stdout new file mode 100644 index 0000000000000000000000000000000000000000..8e372f758976da6599a1735a358f8906bf6eac93 --- /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 0000000000000000000000000000000000000000..546314d063305f1616e4b7f850842d3f3cd2b6ab --- /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 0000000000000000000000000000000000000000..8f4c80b8aa0b5f29cab0a67c87bc39f36ecd35d3 --- /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