Use unsafe blocks in macros.rs

This commit is contained in:
sourceturner
2026-01-18 21:55:50 +01:00
parent 1af4be27c0
commit b5291171d3
+39 -34
View File
@@ -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 {