From 8420f43b866f1f383092786363bdff90251574b3 Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Sat, 27 Jul 2019 09:28:12 -0500 Subject: [PATCH] libc: minimal: add strspn and strcspn support These functions are useful for determining prefixes, as with file system paths. They are required by littlefs. Signed-off-by: Peter A. Bigot --- lib/libc/minimal/CMakeLists.txt | 1 + lib/libc/minimal/include/string.h | 3 +++ lib/libc/minimal/source/string/strspn.c | 32 +++++++++++++++++++++++++ tests/lib/c_lib/src/main.c | 25 +++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 lib/libc/minimal/source/string/strspn.c diff --git a/lib/libc/minimal/CMakeLists.txt b/lib/libc/minimal/CMakeLists.txt index 4a405eeef4f..3ac2ebade1c 100644 --- a/lib/libc/minimal/CMakeLists.txt +++ b/lib/libc/minimal/CMakeLists.txt @@ -13,6 +13,7 @@ zephyr_library_sources( source/string/strncasecmp.c source/string/strstr.c source/string/string.c + source/string/strspn.c source/stdout/prf.c source/stdout/stdout_console.c source/stdout/sprintf.c diff --git a/lib/libc/minimal/include/string.h b/lib/libc/minimal/include/string.h index 3782d7f4e5c..73a60e7218e 100644 --- a/lib/libc/minimal/include/string.h +++ b/lib/libc/minimal/include/string.h @@ -31,6 +31,9 @@ extern char *strncat(char *_MLIBC_RESTRICT d, const char *_MLIBC_RESTRICT s, size_t n); extern char *strstr(const char *s, const char *find); +extern size_t strspn(const char *s, const char *accept); +extern size_t strcspn(const char *s, const char *reject); + extern int memcmp(const void *m1, const void *m2, size_t n); extern void *memmove(void *d, const void *s, size_t n); extern void *memcpy(void *_MLIBC_RESTRICT d, const void *_MLIBC_RESTRICT s, diff --git a/lib/libc/minimal/source/string/strspn.c b/lib/libc/minimal/source/string/strspn.c new file mode 100644 index 00000000000..3af7d542a7b --- /dev/null +++ b/lib/libc/minimal/source/string/strspn.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Peter Bigot Consulting, LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +size_t strspn(const char *s, + const char *accept) +{ + const char *ins = s; + + while ((*s != '\0') && (strchr(accept, *s) != NULL)) { + ++s; + } + + return s - ins; +} + +size_t strcspn(const char *s, + const char *reject) +{ + const char *ins = s; + + while ((*s != '\0') && (strchr(reject, *s) == NULL)) { + ++s; + } + + return s - ins; +} diff --git a/tests/lib/c_lib/src/main.c b/tests/lib/c_lib/src/main.c index 9f143fd989d..ae2929e738f 100644 --- a/tests/lib/c_lib/src/main.c +++ b/tests/lib/c_lib/src/main.c @@ -249,6 +249,30 @@ void test_strchr(void) } +/** + * + * @brief Test string prefix match functions + * + */ + +void test_strxspn(void) +{ + const char *empty = ""; + const char *cset = "abc"; + + zassert_true(strspn("", empty) == 0U, "strspn empty empty"); + zassert_true(strcspn("", empty) == 0U, "strcspn empty empty"); + + zassert_true(strspn("abde", cset) == 2U, "strspn match"); + zassert_true(strcspn("abde", cset) == 0U, "strcspn nomatch"); + + zassert_true(strspn("da", cset) == 0U, "strspn nomatch"); + zassert_true(strcspn("da", cset) == 1U, "strcspn match"); + + zassert_true(strspn("abac", cset) == 4U, "strspn all"); + zassert_true(strcspn("defg", cset) == 4U, "strcspn all"); +} + /** * * @brief Test memory comparison function @@ -310,6 +334,7 @@ void test_main(void) ztest_unit_test(test_memset), ztest_unit_test(test_strlen), ztest_unit_test(test_strcmp), + ztest_unit_test(test_strxspn), ztest_unit_test(test_bsearch) ); ztest_run_test_suite(test_c_lib);