diff --git a/Tests/LibC/TestWchar.cpp b/Tests/LibC/TestWchar.cpp index ed248531a3..949d9ad83c 100644 --- a/Tests/LibC/TestWchar.cpp +++ b/Tests/LibC/TestWchar.cpp @@ -35,6 +35,36 @@ TEST_CASE(wcspbrk) EXPECT_EQ(ret, input + 2); } +TEST_CASE(wcsstr) +{ + const wchar_t* input = L"abcde"; + wchar_t* ret; + + // Empty needle should return haystack. + ret = wcsstr(input, L""); + EXPECT_EQ(ret, input); + + // Test exact match. + ret = wcsstr(input, input); + EXPECT_EQ(ret, input); + + // Test match at string start. + ret = wcsstr(input, L"ab"); + EXPECT_EQ(ret, input); + + // Test match at string end. + ret = wcsstr(input, L"de"); + EXPECT_EQ(ret, input + 3); + + // Test no match. + ret = wcsstr(input, L"z"); + EXPECT_EQ(ret, nullptr); + + // Test needle that is longer than the haystack. + ret = wcsstr(input, L"abcdef"); + EXPECT_EQ(ret, nullptr); +} + TEST_CASE(wcscoll) { // Check if wcscoll is sorting correctly. At the moment we are doing raw char comparisons, diff --git a/Userland/Libraries/LibC/wchar.cpp b/Userland/Libraries/LibC/wchar.cpp index 39eb3e8579..db255185af 100644 --- a/Userland/Libraries/LibC/wchar.cpp +++ b/Userland/Libraries/LibC/wchar.cpp @@ -355,4 +355,24 @@ wchar_t* wcspbrk(const wchar_t* wcs, const wchar_t* accept) return nullptr; } + +wchar_t* wcsstr(const wchar_t* haystack, const wchar_t* needle) +{ + size_t nlen = wcslen(needle); + + if (nlen == 0) + return const_cast(haystack); + + size_t hlen = wcslen(haystack); + + while (hlen >= nlen) { + if (wcsncmp(haystack, needle, nlen) == 0) + return const_cast(haystack); + + haystack++; + hlen--; + } + + return nullptr; +} } diff --git a/Userland/Libraries/LibC/wchar.h b/Userland/Libraries/LibC/wchar.h index 98c6824945..70ea7006a8 100644 --- a/Userland/Libraries/LibC/wchar.h +++ b/Userland/Libraries/LibC/wchar.h @@ -42,5 +42,6 @@ int wcscoll(const wchar_t*, const wchar_t*); int wctob(wint_t); int mbsinit(const mbstate_t*); wchar_t* wcspbrk(const wchar_t*, const wchar_t*); +wchar_t* wcsstr(const wchar_t*, const wchar_t*); __END_DECLS