Quellcode durchsuchen

* create basic strtok
* add test and expected output

Timothy Bess vor 7 Jahren
Ursprung
Commit
f60fafe8fb

+ 1 - 0
.gitignore

@@ -1 +1,2 @@
 /target/
+.idea/

+ 31 - 2
src/string/src/lib.rs

@@ -323,8 +323,37 @@ pub unsafe extern "C" fn strstr(s1: *const c_char, s2: *const c_char) -> *mut c_
 }
 
 #[no_mangle]
-pub extern "C" fn strtok(s1: *mut c_char, s2: *const c_char) -> *mut c_char {
-    unimplemented!();
+pub extern "C" fn strtok(s1: *mut c_char, delimiter: *const c_char) -> *mut c_char {
+    // Loosely based on GLIBC implementation
+    unsafe {
+        static mut HAYSTACK: *mut c_char = ptr::null_mut();
+        if !s1.is_null() {
+            HAYSTACK = s1;
+        } else if HAYSTACK.is_null() {
+            return ptr::null_mut();
+        }
+
+        // Skip past any extra delimiter left over from previous call
+        HAYSTACK = HAYSTACK.add(strspn(HAYSTACK, delimiter));
+        if *HAYSTACK == 0 {
+            HAYSTACK = ptr::null_mut();
+            return ptr::null_mut();
+        }
+
+        // Build token by injecting null byte into delimiter
+        let token = HAYSTACK;
+        HAYSTACK = strpbrk(token, delimiter);
+        if !HAYSTACK.is_null() {
+            HAYSTACK.write(0 as c_char);
+            HAYSTACK = HAYSTACK.add(1);
+        } else {
+            HAYSTACK = ptr::null_mut();
+        }
+
+        return token;
+    }
+
+    ptr::null_mut()
 }
 
 #[no_mangle]

+ 1 - 0
tests/Makefile

@@ -29,6 +29,7 @@ EXPECT_BINS=\
 	string/strspn \
 	string/strstr \
 	string/strpbrk \
+	string/strtok \
 	unlink \
 	waitpid \
 	write

+ 0 - 0
tests/expected/string/strtok.stderr


+ 2 - 0
tests/expected/string/strtok.stdout

@@ -0,0 +1,2 @@
+I'd_just_like_to_interject_for_a_moment.__What_you're_referring_to_as_Linux,
+is_in_fact,_GNU/Linux,_or_as_I've_recently_taken_to_calling_it,_GNU_plus_Linux.

+ 15 - 0
tests/string/strtok.c

@@ -0,0 +1,15 @@
+#include <string.h>
+#include <stdio.h>
+
+int main(int argc, char* argv[]) {
+    char source[] = "I'd just like to interject for a moment.  What you're referring to as Linux, "
+                    "is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux.\n";
+
+    char* token = strtok(source, " ");
+    while (token) {
+        printf("%s_", token);
+        token = strtok(NULL, " ");
+    }
+
+    return 0;
+}