diff --git a/libc/include/string.h b/libc/include/string.h index d075e94f..3349a828 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -23,6 +23,9 @@ extern "C" /* Copy n bytes of memory from src to dest, where src and dest may overlap. */ void* memmove(void* dest, const void* src, size_t n); + /* Find the character c in n bytes of memory.*/ + void* memchr(const void* buf, int c, size_t n); + /* Return the length of a null-terminated string. */ size_t strlen(const char* str); @@ -80,6 +83,9 @@ extern "C" /* Copy up to max bytes of src into dest, adding a null terminator at the end. */ size_t strlcpy(char* dest, const char* src, size_t max); + /* Locate a string (needle) in another one (haystack). */ + char* strstr(const char* haystack, const char* needle); + #ifdef __cplusplus } #endif diff --git a/libluna/include/luna/CString.h b/libluna/include/luna/CString.h index fc621a8d..13ff6855 100644 --- a/libluna/include/luna/CString.h +++ b/libluna/include/luna/CString.h @@ -7,6 +7,7 @@ extern "C" void* memset(void* buf, int c, usize n); int memcmp(const void* a, const void* b, usize n); void* memmove(void* dest, const void* src, usize n); + void* memchr(const void* buf, int c, size_t n); usize strlen(const char* str); usize strnlen(const char* str, usize max); @@ -38,4 +39,6 @@ extern "C" char* strrchr(const char* str, int c); char* strpbrk(const char* s, const char* accept); + + char* strstr(const char* haystack, const char* needle); } diff --git a/libluna/src/CString.cpp b/libluna/src/CString.cpp index 4f9e7220..3dcc4581 100644 --- a/libluna/src/CString.cpp +++ b/libluna/src/CString.cpp @@ -15,6 +15,15 @@ extern "C" return buf; } + void* memchr(const void* buf, int c, usize n) + { + for (usize i = 0; i < n; ++i) + { + if (*((const u8*)buf + i) == (u8)c) return const_cast(buf); + } + return nullptr; + } + int memcmp(const void* a, const void* b, usize n) { if (!n) return 0; @@ -264,4 +273,28 @@ extern "C" return nullptr; } + + char* strstr(const char* haystack, const char* needle) + { + const char* i = haystack; // keeps track of the current haystack position + const char* j = needle; // keeps track of the current needle position + const char* k = haystack; // keeps track of the first matched character + + while (*i) + { + if (*j == 0) return const_cast(k); + if (*i != *j) + { + j = needle; + k = i + 1; + } + else + j++; + i++; + } + + if (*j == 0) return const_cast(k); + + return nullptr; + } } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d4d076ec..7749593c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -20,6 +20,7 @@ luna_test(libluna/TestFormat.cpp TestFormat) luna_test(libluna/TestHashTable.cpp TestHashTable) luna_test(libluna/TestCPath.cpp TestCPath) luna_test(libc/TestScanf.cpp TestScanf) +luna_test(libc/TestString.cpp TestString) luna_app(run-tests.cpp run-tests) endif() diff --git a/tests/libc/TestString.cpp b/tests/libc/TestString.cpp new file mode 100644 index 00000000..8a4aac7d --- /dev/null +++ b/tests/libc/TestString.cpp @@ -0,0 +1,24 @@ +#include +#include + +TestResult test_strstr() +{ + const char* find = "Hello, world!"; + + validate(strstr(find, "Hello") == find); + validate(strstr(find, "!") == find + 12); + validate(strstr(find, "world") == find + 7); + validate(strstr(find, "Hullo") == nullptr); + validate(strstr(find, "notfound") == nullptr); + + test_success; +} + +Result test_main() +{ + test_prelude; + + run_test(test_strstr); + + return {}; +} diff --git a/tools/make-iso.sh b/tools/make-iso.sh index 1ab9cba0..37b3d2c4 100755 --- a/tools/make-iso.sh +++ b/tools/make-iso.sh @@ -7,6 +7,6 @@ cd $LUNA_ROOT fakeroot -u -s $LUNA_ROOT/.fakeroot -- tools/install.sh -fakeroot -u -i $LUNA_ROOT/.fakeroot -- genext2fs -d base -B 4096 -b 1024 -L luna-rootfs -N 1024 build/ext2fs.bin +fakeroot -u -i $LUNA_ROOT/.fakeroot -- genext2fs -d base -B 4096 -b 2048 -L luna-rootfs -N 2048 build/ext2fs.bin mkbootimg luna.json Luna.iso diff --git a/tools/run-tests.sh b/tools/run-tests.sh index bf93adbb..4c85717d 100755 --- a/tools/run-tests.sh +++ b/tools/run-tests.sh @@ -14,9 +14,9 @@ tools/install-headers.sh cmake -S . -B $LUNA_BUILD_DIR -G "$LUNA_CMAKE_GENERATOR_NAME" -DBUILD_TESTS=ON cmake --build $LUNA_BUILD_DIR -rm initrd/etc/init/* +rm base/etc/init/* -printf "Name=test\nCommand=/bin/run-tests\nWait=true\n" > initrd/etc/init/00-tests +printf "Name=test\nCommand=/bin/run-tests\nWait=true\n" > base/etc/init/00-tests tools/make-iso.sh @@ -24,6 +24,6 @@ set +e tools/fast-run.sh set -e -rm initrd/etc/init/00-tests +rm base/etc/init/00-tests -git checkout initrd/etc/init/ +git checkout base/etc/init/