Merge branch 'verify-inttypes-includes' into 'master'
Verify inttypes includes See merge request redox-os/relibc!1100
This commit is contained in:
@@ -1,4 +1,11 @@
|
||||
sys_includes = ["stdint.h", "wchar.h"]
|
||||
# POSIX header spec: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/inttypes.h.html
|
||||
#
|
||||
# Spec quotations relating to includes:
|
||||
# - "The <inttypes.h> header shall include the <stdint.h> header."
|
||||
# - "wchar_t As described in <stddef.h>."
|
||||
#
|
||||
# bits/wchar.h brings in both stdint.h and stddef.h
|
||||
sys_includes = ["bits/wchar.h"]
|
||||
include_guard = "_RELIBC_INTTYPES_H"
|
||||
trailer = "#include <bits/inttypes.h>"
|
||||
language = "C"
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/inttypes.h.html>.
|
||||
|
||||
use crate::{
|
||||
header::{ctype, errno::*, stdlib::*},
|
||||
header::{
|
||||
ctype::{self, isspace},
|
||||
errno::*,
|
||||
stdlib::*,
|
||||
},
|
||||
platform::{
|
||||
self,
|
||||
types::{c_char, c_int, c_long, intmax_t, uintmax_t},
|
||||
types::{c_char, c_int, c_long, intmax_t, uintmax_t, wchar_t},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -68,4 +72,32 @@ pub unsafe extern "C" fn strtoumax(
|
||||
)
|
||||
}
|
||||
|
||||
// wcstoimax(), wcstoumax() currently defined in header::wchar?
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcstoimax.html>.
|
||||
#[unsafe(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() {
|
||||
unsafe { *end = ptr.cast_mut() };
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcstoimax.html>.
|
||||
#[unsafe(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() {
|
||||
unsafe { *end = ptr.cast_mut() };
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
+1
-115
@@ -21,7 +21,7 @@ use crate::{
|
||||
self, ERRNO,
|
||||
types::{
|
||||
c_char, c_double, c_int, c_long, c_longlong, c_uchar, c_ulong, c_ulonglong, c_void,
|
||||
intmax_t, size_t, uintmax_t, wchar_t, wint_t,
|
||||
size_t, wchar_t, wint_t,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -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 <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcstod.html>.
|
||||
#[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 <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcstol.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn wcstol(
|
||||
@@ -951,21 +867,6 @@ pub unsafe extern "C" fn wcstoll(
|
||||
result
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcstoimax.html>.
|
||||
#[unsafe(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() {
|
||||
unsafe { *end = ptr.cast_mut() };
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcstoul.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn wcstoul(
|
||||
@@ -996,21 +897,6 @@ pub unsafe extern "C" fn wcstoull(
|
||||
result
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcstoimax.html>.
|
||||
#[unsafe(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() {
|
||||
unsafe { *end = ptr.cast_mut() };
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/009604499/functions/wcswcs.html>.
|
||||
///
|
||||
/// Marked legacy in issue 6.
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user