From 0e766c6b53dd699f1c877ba36c322f3d052461d4 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 8 Mar 2018 20:17:45 -0700 Subject: [PATCH 1/3] 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 6e07d91191..91daf313a3 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 d1ce976cbd..6d9ec1f896 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(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(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::()); + + w.write_fmt(format_args!("{}", a)); + + found_percent = false; + }, 'n' => { let _a = ap.get::(); diff --git a/src/stdlib/Cargo.toml b/src/stdlib/Cargo.toml index 4a2fb9f88e..97f5d44187 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 fd25f5b731..1bc1ff4e46 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) -> 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 81c3450f8a..073101f0f5 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 03c2a97cc3..1d03ad22b4 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 0000000000..b6668aab89 --- /dev/null +++ b/tests/atof.c @@ -0,0 +1,8 @@ +#include +#include + +int main(int argc, char* argv[]) { + double d = atof("1.0"); + printf("%f\n", d); + return 0; +} From 56e304a2afa9ab265e06558d3ef25fdba43c63e0 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 8 Mar 2018 20:20:21 -0700 Subject: [PATCH 2/3] Fix format --- src/stdio/src/printf.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stdio/src/printf.rs b/src/stdio/src/printf.rs index 6d9ec1f896..ead0a05cf3 100644 --- a/src/stdio/src/printf.rs +++ b/src/stdio/src/printf.rs @@ -34,14 +34,14 @@ pub unsafe fn printf(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::()); w.write_fmt(format_args!("{}", a)); found_percent = false; - }, + } 'n' => { let _a = ap.get::(); From a95a0342197fc20185fbc5ab688ef1619a2b5608 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 8 Mar 2018 20:54:46 -0700 Subject: [PATCH 3/3] Fix issues by adding support for floating point values in va_list --- src/stdio/src/printf.rs | 2 +- tests/atof.c | 2 +- va_list | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stdio/src/printf.rs b/src/stdio/src/printf.rs index ead0a05cf3..54ce1f7644 100644 --- a/src/stdio/src/printf.rs +++ b/src/stdio/src/printf.rs @@ -36,7 +36,7 @@ pub unsafe fn printf(mut w: W, format: *const c_char, mut ap: VaL found_percent = false; } 'f' | 'F' => { - let a: f64 = mem::transmute(ap.get::()); + let a = ap.get::(); w.write_fmt(format_args!("{}", a)); diff --git a/tests/atof.c b/tests/atof.c index b6668aab89..1bfb9d0e22 100644 --- a/tests/atof.c +++ b/tests/atof.c @@ -2,7 +2,7 @@ #include int main(int argc, char* argv[]) { - double d = atof("1.0"); + double d = atof("-3.14"); printf("%f\n", d); return 0; } diff --git a/va_list b/va_list index 4762a18450..1945668b2f 160000 --- a/va_list +++ b/va_list @@ -1 +1 @@ -Subproject commit 4762a184501beedbb58ea218f0c84fea85685c35 +Subproject commit 1945668b2fc6e96c498003dce700ebaf95108fac