From 18283feac1ba5e1bc8f3710272de1a842de5c8d8 Mon Sep 17 00:00:00 2001 From: Tom Almeida Date: Sat, 10 Mar 2018 22:58:35 +0800 Subject: [PATCH 1/4] Added implementations of strchr, strcspn and strspn --- src/string/src/lib.rs | 67 ++++++++++++++++++++++++++++++++++++++---- tests/.gitignore | 3 ++ tests/Makefile | 3 ++ tests/string/strchr.c | 10 +++++++ tests/string/strcspn.c | 9 ++++++ tests/string/strspn.c | 10 +++++++ 6 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 tests/string/strchr.c create mode 100644 tests/string/strcspn.c create mode 100644 tests/string/strspn.c diff --git a/src/string/src/lib.rs b/src/string/src/lib.rs index a3d454fe7e..7914b57cec 100644 --- a/src/string/src/lib.rs +++ b/src/string/src/lib.rs @@ -90,8 +90,19 @@ pub unsafe extern "C" fn strcat(s1: *mut c_char, s2: *const c_char) -> *mut c_ch } #[no_mangle] -pub extern "C" fn strchr(s: *const c_char, c: c_int) -> *mut c_char { - unimplemented!(); +pub unsafe extern "C" fn strchr(s: *const c_char, c: c_int) -> *mut c_char { + let c = c as i8; + let mut i = 0; + loop { + let cur = *s.offset(i); + if cur == c { + return s.offset(i) as *mut c_char; + } + if cur == 0 { + return ptr::null_mut(); + } + i += 1; + } } #[no_mangle] @@ -110,8 +121,30 @@ pub unsafe extern "C" fn strcpy(s1: *mut c_char, s2: *const c_char) -> *mut c_ch } #[no_mangle] -pub extern "C" fn strcspn(s1: *const c_char, s2: *const c_char) -> c_ulong { - unimplemented!(); +pub unsafe extern "C" fn strcspn(s1: *const c_char, s2: *const c_char) -> c_ulong { + use core::mem; + + let s1 = s1 as *const u8; + let s2 = s2 as *const u8; + + // The below logic is effectively ripped from the musl implementation + + let mut byteset = [0u8; 32/mem::size_of::()]; + + let mut i = 0; + while *s2.offset(i) != 0 { + byteset[(*s2.offset(i) as usize)/(8*mem::size_of::())] |= 1 << (*s2.offset(i) as usize % (8*mem::size_of::())); + i += 1; + } + + i = 0; // reset + while *s2.offset(i) != 0 { + if byteset[(*s2.offset(i) as usize)/(8*mem::size_of::())] & 1 << (*s2.offset(i) as usize % (8*mem::size_of::())) > 0 { + break; + } + i += 1; + } + i as u64 } #[no_mangle] @@ -228,8 +261,30 @@ pub extern "C" fn strrchr(s: *const c_char, c: c_int) -> *mut c_char { } #[no_mangle] -pub extern "C" fn strspn(s1: *const c_char, s2: *const c_char) -> c_ulong { - unimplemented!(); +pub unsafe extern "C" fn strspn(s1: *const c_char, s2: *const c_char) -> c_ulong { + use core::mem; + + let s1 = s1 as *const u8; + let s2 = s2 as *const u8; + + // The below logic is effectively ripped from the musl implementation + + let mut byteset = [0u8; 32/mem::size_of::()]; + + let mut i = 0; + while *s2.offset(i) != 0 { + byteset[(*s2.offset(i) as usize)/(8*mem::size_of::())] |= 1 << (*s2.offset(i) as usize % (8*mem::size_of::())); + i += 1; + } + + i = 0; // reset + while *s2.offset(i) != 0 { + if byteset[(*s2.offset(i) as usize)/(8*mem::size_of::())] & 1 << (*s2.offset(i) as usize % (8*mem::size_of::())) < 1 { + break; + } + i += 1; + } + i as u64 } #[no_mangle] diff --git a/tests/.gitignore b/tests/.gitignore index 0c582647ba..929fcc62d7 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -30,5 +30,8 @@ /sprintf /stdlib/strtol /string/strncmp +/string/strcspn +/string/strchr +/string/strspn /unlink /write diff --git a/tests/Makefile b/tests/Makefile index 0726ba101b..49c313a55d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -25,6 +25,9 @@ BINS=\ sprintf \ stdlib/strtol \ string/strncmp \ + string/strcspn \ + string/strchr \ + string/strspn \ unlink \ write diff --git a/tests/string/strchr.c b/tests/string/strchr.c new file mode 100644 index 0000000000..929c22bede --- /dev/null +++ b/tests/string/strchr.c @@ -0,0 +1,10 @@ +#include +#include + +int main(int argc, char* argv[]) { + printf("%s\n", strchr("hello", 'e')); // should be ello + printf("%s\n", strchr("world", 'l')); // should be ld + printf("%s\n", strchr("world", 0)); // should be '' + + return 0; +} diff --git a/tests/string/strcspn.c b/tests/string/strcspn.c new file mode 100644 index 0000000000..fa433d7e4f --- /dev/null +++ b/tests/string/strcspn.c @@ -0,0 +1,9 @@ +#include +#include + +int main(int argc, char* argv[]) { + printf("%ld\n", strcspn("hello", "world")); // should be 2 + printf("%ld\n", strcspn("banana", "world")); // should be 6 + + return 0; +} diff --git a/tests/string/strspn.c b/tests/string/strspn.c new file mode 100644 index 0000000000..9e4fc70c5b --- /dev/null +++ b/tests/string/strspn.c @@ -0,0 +1,10 @@ +#include +#include + +int main(int argc, char* argv[]) { + printf("%lu\n", strspn("hello", "hello")); // should be 5 + printf("%lu\n", strspn("world", "wendy")); // should be 1 + printf("%lu\n", strspn("banana", "apple")); // should be 0 + + return 0; +} From 87ec6dfacbd1e8ac7a58be39a2925dbcd4eb85fd Mon Sep 17 00:00:00 2001 From: Tom Almeida Date: Sat, 10 Mar 2018 22:59:24 +0800 Subject: [PATCH 2/4] Fixed unused variable in memchr --- src/string/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/string/src/lib.rs b/src/string/src/lib.rs index 7914b57cec..101961615e 100644 --- a/src/string/src/lib.rs +++ b/src/string/src/lib.rs @@ -39,7 +39,6 @@ pub unsafe extern "C" fn memccpy( pub unsafe extern "C" fn memchr(s: *const c_void, c: c_int, n: usize) -> *mut c_void { let s = s as *mut u8; let c = c as u8; - let mut i = 0; for i in 0..n { if *s.offset(i as isize) == c { return s.offset(i as isize) as *mut c_void; From b0f8e31b6369e4821aad6c51bbdcd317e5974bb5 Mon Sep 17 00:00:00 2001 From: Tom Almeida Date: Sat, 10 Mar 2018 23:01:49 +0800 Subject: [PATCH 3/4] ran fmt.sh --- src/string/src/lib.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/string/src/lib.rs b/src/string/src/lib.rs index 101961615e..5a6eb9bfa5 100644 --- a/src/string/src/lib.rs +++ b/src/string/src/lib.rs @@ -125,20 +125,23 @@ pub unsafe extern "C" fn strcspn(s1: *const c_char, s2: *const c_char) -> c_ulon let s1 = s1 as *const u8; let s2 = s2 as *const u8; - + // The below logic is effectively ripped from the musl implementation - let mut byteset = [0u8; 32/mem::size_of::()]; + let mut byteset = [0u8; 32 / mem::size_of::()]; let mut i = 0; while *s2.offset(i) != 0 { - byteset[(*s2.offset(i) as usize)/(8*mem::size_of::())] |= 1 << (*s2.offset(i) as usize % (8*mem::size_of::())); + byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::())] |= + 1 << (*s2.offset(i) as usize % (8 * mem::size_of::())); i += 1; } i = 0; // reset while *s2.offset(i) != 0 { - if byteset[(*s2.offset(i) as usize)/(8*mem::size_of::())] & 1 << (*s2.offset(i) as usize % (8*mem::size_of::())) > 0 { + if byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::())] + & 1 << (*s2.offset(i) as usize % (8 * mem::size_of::())) > 0 + { break; } i += 1; @@ -265,20 +268,23 @@ pub unsafe extern "C" fn strspn(s1: *const c_char, s2: *const c_char) -> c_ulong let s1 = s1 as *const u8; let s2 = s2 as *const u8; - + // The below logic is effectively ripped from the musl implementation - let mut byteset = [0u8; 32/mem::size_of::()]; + let mut byteset = [0u8; 32 / mem::size_of::()]; let mut i = 0; while *s2.offset(i) != 0 { - byteset[(*s2.offset(i) as usize)/(8*mem::size_of::())] |= 1 << (*s2.offset(i) as usize % (8*mem::size_of::())); + byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::())] |= + 1 << (*s2.offset(i) as usize % (8 * mem::size_of::())); i += 1; } i = 0; // reset while *s2.offset(i) != 0 { - if byteset[(*s2.offset(i) as usize)/(8*mem::size_of::())] & 1 << (*s2.offset(i) as usize % (8*mem::size_of::())) < 1 { + if byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::())] + & 1 << (*s2.offset(i) as usize % (8 * mem::size_of::())) < 1 + { break; } i += 1; From d0bf830ca7c857a09b0dac4c843d7d6d1eb34a56 Mon Sep 17 00:00:00 2001 From: Tom Almeida Date: Sat, 10 Mar 2018 23:09:10 +0800 Subject: [PATCH 4/4] fixed a logic error in strchr --- src/string/src/lib.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/string/src/lib.rs b/src/string/src/lib.rs index 5a6eb9bfa5..b639cf2e53 100644 --- a/src/string/src/lib.rs +++ b/src/string/src/lib.rs @@ -92,16 +92,13 @@ pub unsafe extern "C" fn strcat(s1: *mut c_char, s2: *const c_char) -> *mut c_ch pub unsafe extern "C" fn strchr(s: *const c_char, c: c_int) -> *mut c_char { let c = c as i8; let mut i = 0; - loop { - let cur = *s.offset(i); - if cur == c { + while *s.offset(i) != 0 { + if *s.offset(i) == c { return s.offset(i) as *mut c_char; } - if cur == 0 { - return ptr::null_mut(); - } i += 1; } + ptr::null_mut() } #[no_mangle]