Przeglądaj źródła

add asctime

Signed-off-by: Marat Safin <[email protected]>
Marat Safin 7 lat temu
rodzic
commit
ff37adeeba
7 zmienionych plików z 55 dodań i 3 usunięć
  1. 1 0
      Cargo.lock
  2. 1 0
      src/time/Cargo.toml
  3. 5 0
      src/time/src/constants.rs
  4. 29 2
      src/time/src/lib.rs
  5. 1 0
      tests/.gitignore
  6. 2 1
      tests/Makefile
  7. 16 0
      tests/asctime.c

+ 1 - 0
Cargo.lock

@@ -514,6 +514,7 @@ name = "time"
 version = "0.1.0"
 dependencies = [
  "cbindgen 0.5.2",
+ "errno 0.1.0",
  "platform 0.1.0",
 ]
 

+ 1 - 0
src/time/Cargo.toml

@@ -9,3 +9,4 @@ cbindgen = { path = "../../cbindgen" }
 
 [dependencies]
 platform = { path = "../platform" }
+errno = { path = "../errno" }

+ 5 - 0
src/time/src/constants.rs

@@ -37,3 +37,8 @@ pub(crate) const DAYSPERWEEK: c_int = 7;
 pub(crate) const YEAR_BASE: c_int = 1900;
 
 pub(crate) const UTC: *const c_char = b"UTC\0" as *const u8 as *const c_char;
+
+pub(crate) const DAY_NAMES: [&str; 7] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+pub(crate) const MON_NAMES: [&str; 12] = [
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+];

+ 29 - 2
src/time/src/lib.rs

@@ -3,6 +3,7 @@
 #![no_std]
 #![feature(const_fn)]
 
+extern crate errno;
 extern crate platform;
 
 pub mod constants;
@@ -11,6 +12,9 @@ mod helpers;
 use platform::types::*;
 use constants::*;
 use helpers::*;
+use core::fmt::write;
+use core::mem::transmute;
+use errno::EIO;
 
 /*
  *#[repr(C)]
@@ -52,6 +56,9 @@ static mut TM: tm = tm {
     tm_zone: UTC,
 };
 
+// The C Standard says that ctime and asctime return the same pointer.
+static mut ASCTIME: [c_char; 26] = [0; 26];
+
 #[repr(C)]
 pub struct itimerspec {
     pub it_interval: timespec,
@@ -62,12 +69,32 @@ pub struct sigevent;
 
 #[no_mangle]
 pub extern "C" fn asctime(timeptr: *const tm) -> *mut c_char {
-    unimplemented!();
+    unsafe { asctime_r(timeptr, transmute::<&mut _, *mut c_char>(&mut ASCTIME)) }
 }
 
 #[no_mangle]
 pub extern "C" fn asctime_r(tm: *const tm, buf: *mut c_char) -> *mut c_char {
-    unimplemented!();
+    let tm = unsafe { &*tm };
+    let result = core::fmt::write(
+        &mut platform::UnsafeStringWriter(buf as *mut u8),
+        format_args!(
+            "{:.3} {:.3}{:3} {:02}:{:02}:{:02} {}\n",
+            DAY_NAMES[tm.tm_wday as usize],
+            MON_NAMES[tm.tm_mon as usize],
+            tm.tm_mday as usize,
+            tm.tm_hour as usize,
+            tm.tm_min as usize,
+            tm.tm_sec as usize,
+            (1900 + tm.tm_year)
+        ),
+    );
+    match result {
+        Ok(_) => buf,
+        Err(_) => {
+            unsafe { platform::errno = EIO };
+            core::ptr::null_mut()
+        }
+    }
 }
 
 #[no_mangle]

+ 1 - 0
tests/.gitignore

@@ -50,3 +50,4 @@
 /write
 /time
 /gmtime
+/asctime

+ 2 - 1
tests/Makefile

@@ -44,7 +44,8 @@ EXPECT_BINS=\
 	waitpid \
 	write \
 	time \
-	gmtime
+	gmtime \
+	asctime
 
 # Binaries that may generate varied output
 BINS=\

+ 16 - 0
tests/asctime.c

@@ -0,0 +1,16 @@
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char** argv) {
+    time_t a = 0;
+    tm *time_info = gmtime(&a);
+
+    char *time_string = asctime(time_info);
+
+    if (time_string == NULL || strcmp(time_string, "Thu Jan  1 00:00:00 1970\n") != 0) {
+        exit(1);
+    }
+    return 0;
+}