Browse Source

string: implement strcat, strcmp, strcpy, and strdup

Alex Lyon 7 years ago
parent
commit
9f39456dbd
4 changed files with 27 additions and 19 deletions
  1. 1 0
      Cargo.lock
  2. 2 11
      src/platform/src/lib.rs
  3. 1 0
      src/string/Cargo.toml
  4. 23 8
      src/string/src/lib.rs

+ 1 - 0
Cargo.lock

@@ -454,6 +454,7 @@ version = "0.1.0"
 dependencies = [
  "cbindgen 0.5.0",
  "platform 0.1.0",
+ "stdlib 0.1.0",
 ]
 
 [[package]]

+ 2 - 11
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] {

+ 1 - 0
src/string/Cargo.toml

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

+ 23 - 8
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]