Skip to content
Snippets Groups Projects
Unverified Commit ffeefb2a authored by Jeremy Soller's avatar Jeremy Soller Committed by GitHub
Browse files

Merge pull request #61 from Tommoa/master

Add implementations of strspn, strcspn and strchr
parents b52a1d61 d0bf830c
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......@@ -90,8 +89,16 @@ 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;
while *s.offset(i) != 0 {
if *s.offset(i) == c {
return s.offset(i) as *mut c_char;
}
i += 1;
}
ptr::null_mut()
}
#[no_mangle]
......@@ -110,8 +117,33 @@ 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::<usize>()];
let mut i = 0;
while *s2.offset(i) != 0 {
byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::<usize>())] |=
1 << (*s2.offset(i) as usize % (8 * mem::size_of::<usize>()));
i += 1;
}
i = 0; // reset
while *s2.offset(i) != 0 {
if byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::<usize>())]
& 1 << (*s2.offset(i) as usize % (8 * mem::size_of::<usize>())) > 0
{
break;
}
i += 1;
}
i as u64
}
#[no_mangle]
......@@ -228,8 +260,33 @@ 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::<usize>()];
let mut i = 0;
while *s2.offset(i) != 0 {
byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::<usize>())] |=
1 << (*s2.offset(i) as usize % (8 * mem::size_of::<usize>()));
i += 1;
}
i = 0; // reset
while *s2.offset(i) != 0 {
if byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::<usize>())]
& 1 << (*s2.offset(i) as usize % (8 * mem::size_of::<usize>())) < 1
{
break;
}
i += 1;
}
i as u64
}
#[no_mangle]
......
......@@ -30,5 +30,8 @@
/sprintf
/stdlib/strtol
/string/strncmp
/string/strcspn
/string/strchr
/string/strspn
/unlink
/write
......@@ -25,6 +25,9 @@ BINS=\
sprintf \
stdlib/strtol \
string/strncmp \
string/strcspn \
string/strchr \
string/strspn \
unlink \
write
......
#include <string.h>
#include <stdio.h>
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;
}
#include <string.h>
#include <stdio.h>
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;
}
#include <string.h>
#include <stdio.h>
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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment