diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs index 08edbf3374..d41213b18c 100644 --- a/src/header/wchar/mod.rs +++ b/src/header/wchar/mod.rs @@ -759,14 +759,6 @@ pub unsafe extern "C" fn wcsstr(ws1: *const wchar_t, ws2: *const wchar_t) -> *mu } } -macro_rules! skipws { - ($ptr:expr) => { - while isspace(unsafe { *$ptr }) != 0 { - $ptr = unsafe { $ptr.add(1) }; - } - }; -} - /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn wcstod(mut ptr: *const wchar_t, end: *mut *mut wchar_t) -> c_double { @@ -845,82 +837,6 @@ pub unsafe extern "C" fn wcstok( wcs } -macro_rules! strtou_impl { - ($type:ident, $ptr:expr, $base:expr) => { - strtou_impl!($type, $ptr, $base, false) - }; - ($type:ident, $ptr:expr, $base:expr, $negative:expr) => {{ - let mut base = $base; - - if (base == 16 || base == 0) - && unsafe { *$ptr } == '0' as wchar_t - && (unsafe { *$ptr.add(1) } == 'x' as wchar_t - || unsafe { *$ptr.add(1) } == 'X' as wchar_t) - { - $ptr = unsafe { $ptr.add(2) }; - base = 16; - } - - if base == 0 { - base = if unsafe { *$ptr } == '0' as wchar_t { - 8 - } else { - 10 - }; - }; - - let mut result: $type = 0; - while let Some(digit) = - char::from_u32(unsafe { *$ptr } as u32).and_then(|c| c.to_digit(base as u32)) - { - let new = result.checked_mul(base as $type).and_then(|result| { - if $negative { - #[cfg(target_arch = "x86")] - { - result.checked_sub( - $type::try_from(digit).expect("single digit never overflows"), - ) - } - #[cfg(not(target_arch = "x86"))] - { - result.checked_sub($type::from(digit)) - } - } else { - #[cfg(target_arch = "x86")] - { - result.checked_add( - $type::try_from(digit).expect("single digit never overflows"), - ) - } - #[cfg(not(target_arch = "x86"))] - { - result.checked_add($type::from(digit)) - } - } - }); - result = match new { - Some(new) => new, - None => { - platform::ERRNO.set(ERANGE); - return !0; - } - }; - - $ptr = unsafe { $ptr.add(1) }; - } - result - }}; -} -macro_rules! strto_impl { - ($type:ident, $ptr:expr, $base:expr) => {{ - let negative = unsafe { *$ptr } == '-' as wchar_t; - if negative { - $ptr = unsafe { $ptr.add(1) }; - } - strtou_impl!($type, $ptr, $base, negative) - }}; -} - /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn wcstol( diff --git a/src/macros.rs b/src/macros.rs index 51440365e2..1b718eb8b2 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -117,8 +117,86 @@ macro_rules! trace_expr { }); } +#[macro_export] +macro_rules! skipws { + ($ptr:expr) => { + while isspace(unsafe { *$ptr }) != 0 { + $ptr = unsafe { $ptr.add(1) }; + } + }; +} + +#[macro_export] +macro_rules! strtou_impl { + ($type:ident, $ptr:expr, $base:expr) => { + strtou_impl!($type, $ptr, $base, false) + }; + ($type:ident, $ptr:expr, $base:expr, $negative:expr) => {{ + let mut base = $base; + + if (base == 16 || base == 0) + && unsafe { *$ptr } == '0' as wchar_t + && (unsafe { *$ptr.add(1) } == 'x' as wchar_t + || unsafe { *$ptr.add(1) } == 'X' as wchar_t) + { + $ptr = unsafe { $ptr.add(2) }; + base = 16; + } + + if base == 0 { + base = if unsafe { *$ptr } == '0' as wchar_t { + 8 + } else { + 10 + }; + }; + + let mut result: $type = 0; + while let Some(digit) = + char::from_u32(unsafe { *$ptr } as u32).and_then(|c| c.to_digit(base as u32)) + { + let new = result.checked_mul(base as $type).and_then(|result| { + if $negative { + #[cfg(target_arch = "x86")] + { + result.checked_sub( + $type::try_from(digit).expect("single digit never overflows"), + ) + } + #[cfg(not(target_arch = "x86"))] + { + result.checked_sub($type::from(digit)) + } + } else { + #[cfg(target_arch = "x86")] + { + result.checked_add( + $type::try_from(digit).expect("single digit never overflows"), + ) + } + #[cfg(not(target_arch = "x86"))] + { + result.checked_add($type::from(digit)) + } + } + }); + result = match new { + Some(new) => new, + None => { + platform::ERRNO.set(ERANGE); + return !0; + } + }; + + $ptr = unsafe { $ptr.add(1) }; + } + result + }}; +} + #[macro_export] macro_rules! strto_impl { + // this variant is used by inttypes and stdlib ( $rettype:ty, $signed:expr, $maxval:expr, $minval:expr, $s:ident, $endptr:ident, $base:ident ) => {{ @@ -219,6 +297,14 @@ macro_rules! strto_impl { num }}; + // this variant is used by wchar (also wcstoimax and wcstoumax from inttypes) + ($type:ident, $ptr:expr, $base:expr) => {{ + let negative = unsafe { *$ptr } == '-' as wchar_t; + if negative { + $ptr = unsafe { $ptr.add(1) }; + } + strtou_impl!($type, $ptr, $base, negative) + }}; } #[macro_export]