Added implementations of strchr, strcspn and strspn
This commit is contained in:
+61
-6
@@ -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::<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 +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::<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
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user