Browse Source

Implement atof

Jeremy Soller 7 years ago
parent
commit
0e766c6b53
7 changed files with 40 additions and 10 deletions
  1. 1 0
      Cargo.lock
  2. 9 6
      src/stdio/src/printf.rs
  3. 1 0
      src/stdlib/Cargo.toml
  4. 19 4
      src/stdlib/src/lib.rs
  5. 1 0
      tests/.gitignore
  6. 1 0
      tests/Makefile
  7. 8 0
      tests/atof.c

+ 1 - 0
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",
 ]

+ 9 - 6
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>();
 

+ 1 - 0
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" }

+ 19 - 4
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]

+ 1 - 0
tests/.gitignore

@@ -1,5 +1,6 @@
 /alloc
 /args
+/atof
 /atoi
 /brk
 /chdir

+ 1 - 0
tests/Makefile

@@ -1,5 +1,6 @@
 BINS=\
 	alloc \
+	atof \
 	atoi \
 	brk \
 	args \

+ 8 - 0
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;
+}