Use unsafe blocks in macros.rs
This commit is contained in:
+39
-34
@@ -1,3 +1,6 @@
|
||||
// TODO: set this for entire crate when possible
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
/// Print to stdout
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
@@ -139,7 +142,9 @@ macro_rules! strto_impl {
|
||||
// const input but mut output, yet the man page says
|
||||
// "stores the address of the first invalid character in *endptr"
|
||||
// so obviously it doesn't want us to clone it.
|
||||
*$endptr = $s.offset(idx) as *mut _;
|
||||
unsafe {
|
||||
*$endptr = $s.offset(idx) as *mut _;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -157,12 +162,12 @@ macro_rules! strto_impl {
|
||||
let mut idx = 0;
|
||||
|
||||
// skip any whitespace at the beginning of the string
|
||||
while ctype::isspace(*$s.offset(idx) as c_int) != 0 {
|
||||
while ctype::isspace(unsafe { *$s.offset(idx) } as c_int) != 0 {
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
// check for +/-
|
||||
let positive = match is_positive(*$s.offset(idx)) {
|
||||
let positive = match is_positive(unsafe { *$s.offset(idx) }) {
|
||||
Some((pos, i)) => {
|
||||
idx += i;
|
||||
pos
|
||||
@@ -174,15 +179,15 @@ macro_rules! strto_impl {
|
||||
};
|
||||
|
||||
// convert the string to a number
|
||||
let num_str = $s.offset(idx);
|
||||
let num_str = unsafe { $s.offset(idx) };
|
||||
let res = match $base {
|
||||
0 => detect_base(num_str).and_then(|($base, i)| {
|
||||
0 => unsafe { detect_base(num_str) }.and_then(|($base, i)| {
|
||||
idx += i;
|
||||
convert_integer(num_str.offset(i), $base)
|
||||
unsafe { convert_integer(num_str.offset(i), $base) }
|
||||
}),
|
||||
8 => convert_octal(num_str),
|
||||
16 => convert_hex(num_str),
|
||||
_ => convert_integer(num_str, $base),
|
||||
8 => unsafe { convert_octal(num_str) },
|
||||
16 => unsafe { convert_hex(num_str) },
|
||||
_ => unsafe { convert_integer(num_str, $base) },
|
||||
};
|
||||
|
||||
// check for error parsing octal/hex prefix
|
||||
@@ -231,86 +236,86 @@ macro_rules! strto_float_impl {
|
||||
let mut s = $s;
|
||||
let endptr = $endptr;
|
||||
|
||||
while ctype::isspace(*s as c_int) != 0 {
|
||||
s = s.offset(1);
|
||||
while ctype::isspace(unsafe{*s} as c_int) != 0 {
|
||||
s = unsafe{ s.offset(1)};
|
||||
}
|
||||
|
||||
let mut result: $type = 0.0;
|
||||
let mut exponent: Option<$type> = None;
|
||||
let mut radix = 10;
|
||||
|
||||
let result_sign = match *s as u8 {
|
||||
let result_sign = match unsafe{*s} as u8 {
|
||||
b'-' => {
|
||||
s = s.offset(1);
|
||||
s = unsafe{s.offset(1)};
|
||||
-1.0
|
||||
}
|
||||
b'+' => {
|
||||
s = s.offset(1);
|
||||
s = unsafe{s.offset(1)};
|
||||
1.0
|
||||
}
|
||||
_ => 1.0,
|
||||
};
|
||||
|
||||
let rust_s = CStr::from_ptr(s).to_string_lossy();
|
||||
let rust_s = unsafe{CStr::from_ptr(s)}.to_string_lossy();
|
||||
|
||||
// detect NaN, Inf
|
||||
if rust_s.to_lowercase().starts_with("inf") {
|
||||
result = $type::INFINITY;
|
||||
s = s.offset(3);
|
||||
s = unsafe{s.offset(3)};
|
||||
} else if rust_s.to_lowercase().starts_with("nan") {
|
||||
// we cannot signal negative NaN in LLVM backed languages
|
||||
// https://github.com/rust-lang/rust/issues/73328 , https://github.com/rust-lang/rust/issues/81261
|
||||
result = $type::NAN;
|
||||
s = s.offset(3);
|
||||
s = unsafe{s.offset(3)};
|
||||
} else {
|
||||
if *s as u8 == b'0' && *s.offset(1) as u8 == b'x' {
|
||||
s = s.offset(2);
|
||||
if unsafe{*s} as u8 == b'0' && unsafe{*s.offset(1)} as u8 == b'x' {
|
||||
s = unsafe{s.offset(2)};
|
||||
radix = 16;
|
||||
}
|
||||
|
||||
while let Some(digit) = (*s as u8 as char).to_digit(radix) {
|
||||
while let Some(digit) = (unsafe{*s} as u8 as char).to_digit(radix) {
|
||||
result *= radix as $type;
|
||||
result += digit as $type;
|
||||
s = s.offset(1);
|
||||
s = unsafe{s.offset(1)};
|
||||
}
|
||||
|
||||
if *s as u8 == b'.' {
|
||||
s = s.offset(1);
|
||||
if unsafe{*s} as u8 == b'.' {
|
||||
s = unsafe{s.offset(1)};
|
||||
|
||||
let mut i = 1.0;
|
||||
while let Some(digit) = (*s as u8 as char).to_digit(radix) {
|
||||
while let Some(digit) = (unsafe{*s} as u8 as char).to_digit(radix) {
|
||||
i *= radix as $type;
|
||||
result += digit as $type / i;
|
||||
s = s.offset(1);
|
||||
s = unsafe{s.offset(1)};
|
||||
}
|
||||
}
|
||||
|
||||
let s_before_exponent = s;
|
||||
|
||||
exponent = match (*s as u8, radix) {
|
||||
exponent = match (unsafe{*s} as u8, radix) {
|
||||
(b'e' | b'E', 10) | (b'p' | b'P', 16) => {
|
||||
s = s.offset(1);
|
||||
s = unsafe{s.offset(1)};
|
||||
|
||||
let is_exponent_positive = match *s as u8 {
|
||||
let is_exponent_positive = match unsafe{*s} as u8 {
|
||||
b'-' => {
|
||||
s = s.offset(1);
|
||||
s = unsafe{s.offset(1)};
|
||||
false
|
||||
}
|
||||
b'+' => {
|
||||
s = s.offset(1);
|
||||
s = unsafe{s.offset(1)};
|
||||
true
|
||||
}
|
||||
_ => true,
|
||||
};
|
||||
|
||||
// Exponent digits are always in base 10.
|
||||
if (*s as u8 as char).is_digit(10) {
|
||||
if (unsafe{*s} as u8 as char).is_digit(10) {
|
||||
let mut exponent_value = 0;
|
||||
|
||||
while let Some(digit) = (*s as u8 as char).to_digit(10) {
|
||||
while let Some(digit) = (unsafe{*s} as u8 as char).to_digit(10) {
|
||||
exponent_value *= 10;
|
||||
exponent_value += digit;
|
||||
s = s.offset(1);
|
||||
s = unsafe{s.offset(1)};
|
||||
}
|
||||
|
||||
let exponent_base = match radix {
|
||||
@@ -339,7 +344,7 @@ macro_rules! strto_float_impl {
|
||||
// const input but mut output, yet the man page says
|
||||
// "stores the address of the first invalid character in *endptr"
|
||||
// so obviously it doesn't want us to clone it.
|
||||
*endptr = s as *mut _;
|
||||
unsafe{*endptr = s as *mut _};
|
||||
}
|
||||
|
||||
if let Some(exponent) = exponent {
|
||||
|
||||
Reference in New Issue
Block a user