diff options
Diffstat (limited to 'src/user')
-rw-r--r-- | src/user/app/tests/libc/string.c | 36 | ||||
-rw-r--r-- | src/user/lib/include/string.h | 6 | ||||
-rw-r--r-- | src/user/lib/string.c | 36 |
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; +} |