Skip to content
Snippets Groups Projects
Verified Commit b10fa984 authored by jD91mZM2's avatar jD91mZM2
Browse files

Implement strtod

parent face6f07
No related branches found
No related tags found
No related merge requests found
......@@ -635,19 +635,55 @@ pub extern "C" fn srandom(seed: c_uint) {
}
#[no_mangle]
pub unsafe extern "C" fn strtod(s: *const c_char, endptr: *mut *mut c_char) -> c_double {
// TODO: endptr
pub unsafe extern "C" fn strtod(mut s: *const c_char, endptr: *mut *mut c_char) -> c_double {
while ctype::isspace(*s as c_int) != 0 {
s = s.offset(1);
}
use core::str::FromStr;
let mut result = 0.0;
let mut radix = 10;
let s_str = str::from_utf8_unchecked(platform::c_str(s));
match f64::from_str(s_str) {
Ok(ok) => ok as c_double,
Err(_err) => {
platform::errno = EINVAL;
0.0
let negative = match *s as u8 {
b'-' => { s = s.offset(1); true },
b'+' => { s = s.offset(1); false },
_ => false
};
if *s as u8 == b'0' && *s.offset(1) as u8 == b'x' {
s = s.offset(2);
radix = 16;
}
while let Some(digit) = (*s as u8 as char).to_digit(radix) {
result *= radix as c_double;
result += digit as c_double;
s = s.offset(1);
}
if *s as u8 == b'.' {
s = s.offset(1);
let mut i = 1.0;
while let Some(digit) = (*s as u8 as char).to_digit(radix) {
i *= radix as c_double;
result += digit as c_double / i;
s = s.offset(1);
}
}
if !endptr.is_null() {
// This is stupid, but apparently strto* functions want
// 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 _;
}
if negative {
-result
} else {
result
}
}
pub fn is_positive(ch: c_char) -> Option<(bool, isize)> {
......
......@@ -28,6 +28,7 @@ EXPECT_BINS=\
stdlib/env \
stdlib/mkostemps \
stdlib/rand \
stdlib/strtod \
stdlib/strtol \
stdlib/strtoul \
stdlib/system \
......
H
Hello World!
Hello
H
ello World!
Line 2
Hello
d: 0 Endptr: "a 1 hello"
d: 1 Endptr: " hello"
d: 1 Endptr: " hello 2"
d: 10.123 Endptr: ""
d: 10.123 Endptr: ""
d: -5.3 Endptr: ""
d: 16.071044921875 Endptr: ""
d: 1.13671875 Endptr: ""
d: 3.12890625 Endptr: ""
#include <stdlib.h>
#include <stdio.h>
int main() {
char* endptr = 0;
double d;
char* inputs[] = {
"a 1 hello", " 1 hello", "1 hello 2",
"10.123", "010.123", "-5.3",
"0x10.123", "0x1.23", "0x3.21"
};
for (int i = 0; i < sizeof(inputs) / sizeof(char*); i += 1) {
d = strtod(inputs[i], &endptr);
printf("d: %f Endptr: \"%s\"\n", d, endptr);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment