summaryrefslogtreecommitdiff
path: root/src/user
diff options
context:
space:
mode:
Diffstat (limited to 'src/user')
-rw-r--r--src/user/app/tests/libc/string.c36
-rw-r--r--src/user/lib/include/string.h6
-rw-r--r--src/user/lib/string.c36
3 files changed, 76 insertions, 2 deletions
diff --git a/src/user/app/tests/libc/string.c b/src/user/app/tests/libc/string.c
index 53fe1c0..f865d72 100644
--- a/src/user/app/tests/libc/string.c
+++ b/src/user/app/tests/libc/string.c
@@ -65,9 +65,45 @@ static void test_strtol(void) {
test(!strcmp("hello", end));
}
+static void test_strspn(void) {
+ test(0 == strspn("", "1234"));
+ test(0 == strspn("asdf", "1234"));
+ test(0 == strspn("a2df", "1234"));
+ test(2 == strspn("42df", "1234"));
+ test(4 == strspn("4211", "1234"));
+
+ test(0 == strcspn("", "1234"));
+ test(4 == strcspn("asdf", "1234"));
+ test(1 == strcspn("a2df", "1234"));
+}
+
+static void test_strtok(void) {
+ const char *sep = " \t";
+ {
+ char line[] = "LINE TO BE SEPARATED";
+ test(!strcmp(strtok(line, sep), "LINE"));
+ test(!strcmp(strtok(NULL, sep), "TO"));
+ test(!strcmp(strtok(NULL, sep), "BE"));
+ test(!strcmp(strtok(NULL, sep), "SEPARATED"));
+ for (int i = 0; i < 4; i++)
+ test(strtok(NULL, sep) == NULL);
+ }
+ {
+ char line[] = " LINE TO\tBE \t SEPARATED ";
+ test(!strcmp(strtok(line, sep), "LINE"));
+ test(!strcmp(strtok(NULL, sep), "TO"));
+ test(!strcmp(strtok(NULL, sep), "BE"));
+ test(!strcmp(strtok(NULL, sep), "SEPARATED"));
+ for (int i = 0; i < 4; i++)
+ test(strtok(NULL, sep) == NULL);
+ }
+}
+
void r_libc_string(void) {
run_test(test_memcmp);
run_test(test_memset);
run_test(test_strcmp);
run_test(test_strtol);
+ run_test(test_strspn);
+ run_test(test_strtok);
}
diff --git a/src/user/lib/include/string.h b/src/user/lib/include/string.h
index eda4e48..5cddb61 100644
--- a/src/user/lib/include/string.h
+++ b/src/user/lib/include/string.h
@@ -3,3 +3,9 @@
long strtol(const char *restrict s, char **restrict end, int base);
char *strchr(const char *s, int c);
+
+size_t strspn(const char *s, const char *accept);
+size_t strcspn(const char *s, const char *reject);
+
+char *strtok(char *restrict s, const char *restrict sep);
+char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state);
diff --git a/src/user/lib/string.c b/src/user/lib/string.c
index 9c347d0..ff67399 100644
--- a/src/user/lib/string.c
+++ b/src/user/lib/string.c
@@ -48,9 +48,41 @@ long strtol(const char *restrict s, char **restrict end, int base) {
}
char *strchr(const char *s, int c) {
- while (*s) {
+ for (; *s; s++) {
if (*s == c) return (char*)s;
- s++;
}
return NULL;
}
+
+size_t strspn(const char *s, const char *accept) {
+ size_t l = 0;
+ for (; s[l] && strchr(accept, s[l]); l++);
+ return l;
+}
+
+size_t strcspn(const char *s, const char *reject) {
+ size_t l = 0;
+ for (; s[l] && !strchr(reject, s[l]); l++);
+ return l;
+}
+
+char *strtok(char *restrict s, const char *restrict sep) {
+ static char *state;
+ return strtok_r(s, sep, &state);
+}
+
+char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state) {
+ char *end;
+ if (!s) s = *state;
+ s += strspn(s, sep); /* beginning of token */
+ if (!*s) return NULL;
+
+ end = s + strcspn(s, sep);
+ if (*end) {
+ *end = '\0';
+ *state = end + 1;
+ } else {
+ *state = end;
+ }
+ return s;
+}