From 0e766c6b53dd699f1c877ba36c322f3d052461d4 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Thu, 8 Mar 2018 20:17:45 -0700 Subject: [PATCH] Implement atof --- Cargo.lock | 1 + src/stdio/src/printf.rs | 15 +++++++++------ src/stdlib/Cargo.toml | 1 + src/stdlib/src/lib.rs | 23 +++++++++++++++++++---- tests/.gitignore | 1 + tests/Makefile | 1 + tests/atof.c | 8 ++++++++ 7 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 tests/atof.c diff --git a/Cargo.lock b/Cargo.lock index 6e07d9119..91daf313a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -465,6 +465,7 @@ version = "0.1.0" dependencies = [ "cbindgen 0.5.0", "ctype 0.1.0", + "errno 0.1.0", "platform 0.1.0", "ralloc 1.0.0", ] diff --git a/src/stdio/src/printf.rs b/src/stdio/src/printf.rs index d1ce976cb..6d9ec1f89 100644 --- a/src/stdio/src/printf.rs +++ b/src/stdio/src/printf.rs @@ -1,13 +1,9 @@ -use core::fmt; +use core::{fmt, mem, slice, str}; use platform::types::*; use vl::VaList; pub unsafe fn printf<W: fmt::Write>(mut w: W, format: *const c_char, mut ap: VaList) -> c_int { - use core::fmt::Write; - use core::slice; - use core::str; - extern "C" { fn strlen(s: *const c_char) -> size_t; } @@ -38,7 +34,14 @@ pub unsafe fn printf<W: fmt::Write>(mut w: W, format: *const c_char, mut ap: VaL w.write_fmt(format_args!("{}", a)); found_percent = false; - } + }, + 'f' | 'F' => { + let a: f64 = mem::transmute(ap.get::<u64>()); + + w.write_fmt(format_args!("{}", a)); + + found_percent = false; + }, 'n' => { let _a = ap.get::<c_int>(); diff --git a/src/stdlib/Cargo.toml b/src/stdlib/Cargo.toml index 4a2fb9f88..97f5d4418 100644 --- a/src/stdlib/Cargo.toml +++ b/src/stdlib/Cargo.toml @@ -11,3 +11,4 @@ cbindgen = { path = "../../cbindgen" } platform = { path = "../platform" } ralloc = { path = "../../ralloc", default-features = false } ctype = { path = "../ctype" } +errno = { path = "../errno" } diff --git a/src/stdlib/src/lib.rs b/src/stdlib/src/lib.rs index fd25f5b73..1bc1ff4e4 100644 --- a/src/stdlib/src/lib.rs +++ b/src/stdlib/src/lib.rs @@ -5,9 +5,13 @@ #![feature(global_allocator)] extern crate ctype; +extern crate errno; extern crate platform; extern crate ralloc; +use core::{ptr, str}; + +use errno::*; use platform::types::*; #[global_allocator] @@ -52,8 +56,8 @@ pub unsafe extern "C" fn atexit(func: Option<extern "C" fn()>) -> c_int { } #[no_mangle] -pub extern "C" fn atof(s: *const c_char) -> c_double { - unimplemented!(); +pub unsafe extern "C" fn atof(s: *const c_char) -> c_double { + strtod(s, ptr::null_mut()) } macro_rules! dec_num_from_ascii { @@ -396,8 +400,19 @@ pub extern "C" fn srandom(seed: c_uint) { } #[no_mangle] -pub extern "C" fn strtod(s: *const c_char, endptr: *mut *mut c_char) -> c_double { - unimplemented!(); +pub unsafe extern "C" fn strtod(s: *const c_char, endptr: *mut *mut c_char) -> c_double { + //TODO: endptr + + use core::str::FromStr; + + 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 + } + } } #[no_mangle] diff --git a/tests/.gitignore b/tests/.gitignore index 81c3450f8..073101f0f 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,5 +1,6 @@ /alloc /args +/atof /atoi /brk /chdir diff --git a/tests/Makefile b/tests/Makefile index 03c2a97cc..1d03ad22b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,6 @@ BINS=\ alloc \ + atof \ atoi \ brk \ args \ diff --git a/tests/atof.c b/tests/atof.c new file mode 100644 index 000000000..b6668aab8 --- /dev/null +++ b/tests/atof.c @@ -0,0 +1,8 @@ +#include <stdlib.h> +#include <stdio.h> + +int main(int argc, char* argv[]) { + double d = atof("1.0"); + printf("%f\n", d); + return 0; +} -- GitLab