From 114ee16c21ad97ccbd38831efcc30159b60d5d9f Mon Sep 17 00:00:00 2001 From: Alex Lyon Date: Wed, 7 Mar 2018 05:01:41 -0800 Subject: [PATCH] string: implement strncat, strncmp, and strncpy --- src/platform/src/lib.rs | 15 +++++++++++++ src/string/src/lib.rs | 50 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/platform/src/lib.rs b/src/platform/src/lib.rs index 07be95a337..63fc300c1c 100644 --- a/src/platform/src/lib.rs +++ b/src/platform/src/lib.rs @@ -46,6 +46,21 @@ pub unsafe fn c_str(s: *const c_char) -> &'static [u8] { slice::from_raw_parts(s as *const u8, size as usize) } +pub unsafe fn c_str_n(s: *const c_char, n: usize) -> &'static [u8] { + use core::slice; + + let mut size = 0; + + for _ in 0..n { + if *s.offset(size) == 0 { + break; + } + size += 1; + } + + slice::from_raw_parts(s as *const u8, size as usize) +} + pub struct FileWriter(pub c_int); impl FileWriter { diff --git a/src/string/src/lib.rs b/src/string/src/lib.rs index a12135ce3f..c1b30f2289 100644 --- a/src/string/src/lib.rs +++ b/src/string/src/lib.rs @@ -5,6 +5,7 @@ extern crate platform; use platform::types::*; +use core::cmp; #[no_mangle] pub extern "C" fn memccpy(s1: *mut c_void, s2: *const c_void, c: c_int, n: usize) -> *mut c_void { @@ -98,18 +99,55 @@ pub unsafe extern "C" fn strlen(s: *const c_char) -> size_t { } #[no_mangle] -pub extern "C" fn strncat(s1: *mut c_char, s2: *const c_char, n: usize) -> *mut c_char { - unimplemented!(); +pub unsafe extern "C" fn strncat(s1: *mut c_char, s2: *const c_char, n: usize) -> *mut c_char { + let mut idx = strlen(s1 as *const _) as isize; + for i in 0..n as isize { + if *s2.offset(i) == 0 { + break; + } + + *s1.offset(idx) = *s2.offset(i); + idx += 1; + } + *s1.offset(idx) = 0; + + s1 } #[no_mangle] -pub extern "C" fn strncmp(s1: *const c_char, s2: *const c_char, n: usize) -> c_int { - unimplemented!(); +pub unsafe extern "C" fn strncmp(s1: *const c_char, s2: *const c_char, n: usize) -> c_int { + let s1 = platform::c_str_n(s1, n); + let s2 = platform::c_str_n(s2, n); + + for i in 0..n { + let val = s1[i] - s2[i]; + if val != 0 || s1[i] == 0 { + return val as c_int; + } + } + + 0 } #[no_mangle] -pub extern "C" fn strncpy(s1: *mut c_char, s2: *const c_char, n: usize) -> *mut c_char { - unimplemented!(); +pub unsafe extern "C" fn strncpy(s1: *mut c_char, s2: *const c_char, n: usize) -> *mut c_char { + let s2_slice = platform::c_str_n(s2, n); + let s2_len = s2_slice.len(); + + //memcpy(s1 as *mut _, s2 as *const _, cmp::min(n, s2_len)); + let mut idx = 0; + for _ in 0..cmp::min(n, s2_len) { + *s1.offset(idx as isize) = s2_slice[idx] as c_char; + idx += 1; + } + + // if length of s2 < n, pad s1 with zeroes + for _ in cmp::min(n, s2_len)..n { + *s1.offset(idx as isize) = 0; + idx += 1; + } + + s1 } #[no_mangle]