From 9f39456dbdf7947cf4b71fcbd0d1114bd3d09df1 Mon Sep 17 00:00:00 2001
From: Alex Lyon <arcterus@mail.com>
Date: Wed, 7 Mar 2018 14:06:30 -0800
Subject: [PATCH] string: implement strcat, strcmp, strcpy, and strdup

---
 Cargo.lock              |  1 +
 src/platform/src/lib.rs | 13 ++-----------
 src/string/Cargo.toml   |  1 +
 src/string/src/lib.rs   | 31 +++++++++++++++++++++++--------
 4 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 9c7e66eed..11a8c3c49 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -454,6 +454,7 @@ version = "0.1.0"
 dependencies = [
  "cbindgen 0.5.0",
  "platform 0.1.0",
+ "stdlib 0.1.0",
 ]
 
 [[package]]
diff --git a/src/platform/src/lib.rs b/src/platform/src/lib.rs
index 63fc300c1..39e9018d0 100644
--- a/src/platform/src/lib.rs
+++ b/src/platform/src/lib.rs
@@ -32,18 +32,9 @@ use types::*;
 pub static mut errno: c_int = 0;
 
 pub unsafe fn c_str(s: *const c_char) -> &'static [u8] {
-    use core::slice;
-
-    let mut size = 0;
-
-    loop {
-        if *s.offset(size) == 0 {
-            break;
-        }
-        size += 1;
-    }
+    use core::usize;
 
-    slice::from_raw_parts(s as *const u8, size as usize)
+    c_str_n(s, usize::MAX)
 }
 
 pub unsafe fn c_str_n(s: *const c_char, n: usize) -> &'static [u8] {
diff --git a/src/string/Cargo.toml b/src/string/Cargo.toml
index a5678f9b0..36b34042a 100644
--- a/src/string/Cargo.toml
+++ b/src/string/Cargo.toml
@@ -9,3 +9,4 @@ cbindgen = { path = "../../cbindgen" }
 
 [dependencies]
 platform = { path = "../platform" }
+stdlib = { path = "../stdlib" }
diff --git a/src/string/src/lib.rs b/src/string/src/lib.rs
index c1b30f228..4d1f6f560 100644
--- a/src/string/src/lib.rs
+++ b/src/string/src/lib.rs
@@ -3,9 +3,11 @@
 #![no_std]
 
 extern crate platform;
+extern crate stdlib;
 
 use platform::types::*;
 use core::cmp;
+use core::usize;
 
 #[no_mangle]
 pub extern "C" fn memccpy(s1: *mut c_void, s2: *const c_void, c: c_int, n: usize) -> *mut c_void {
@@ -54,8 +56,8 @@ pub extern "C" fn memchr(s: *const c_void, c: c_int, n: usize) -> *mut c_void {
 // }
 
 #[no_mangle]
-pub extern "C" fn strcat(s1: *mut c_char, s2: *const c_char) -> *mut c_char {
-    unimplemented!();
+pub unsafe extern "C" fn strcat(s1: *mut c_char, s2: *const c_char) -> *mut c_char {
+    strncat(s1, s2, usize::MAX)
 }
 
 #[no_mangle]
@@ -64,8 +66,8 @@ pub extern "C" fn strchr(s: *const c_char, c: c_int) -> *mut c_char {
 }
 
 #[no_mangle]
-pub extern "C" fn strcmp(s1: *const c_char, s2: *const c_char) -> c_int {
-    unimplemented!();
+pub unsafe extern "C" fn strcmp(s1: *const c_char, s2: *const c_char) -> c_int {
+    strncmp(s1, s2, usize::MAX)
 }
 
 #[no_mangle]
@@ -74,8 +76,8 @@ pub extern "C" fn strcoll(s1: *const c_char, s2: *const c_char) -> c_int {
 }
 
 #[no_mangle]
-pub extern "C" fn strcpy(s1: *mut c_char, s2: *const c_char) -> *mut c_char {
-    unimplemented!();
+pub unsafe extern "C" fn strcpy(s1: *mut c_char, s2: *const c_char) -> *mut c_char {
+    strncpy(s1, s2, usize::MAX)
 }
 
 #[no_mangle]
@@ -84,8 +86,21 @@ pub extern "C" fn strcspn(s1: *const c_char, s2: *const c_char) -> c_ulong {
 }
 
 #[no_mangle]
-pub extern "C" fn strdup(s1: *const c_char) -> *mut c_char {
-    unimplemented!();
+pub unsafe extern "C" fn strdup(s1: *const c_char) -> *mut c_char {
+    // the "+ 1" is to account for the NUL byte
+    let len = strlen(s1) + 1;
+
+    let buffer = stdlib::malloc(len) as *mut _;
+    if buffer.is_null() {
+        // TODO: set errno
+    } else {
+        //memcpy(buffer, s1, len)
+        for i in 0..len as isize {
+            *buffer.offset(i) = *s1.offset(i);
+        }
+    }
+
+    buffer
 }
 
 #[no_mangle]
-- 
GitLab