summaryrefslogtreecommitdiff
path: root/libc/test/src/strings
diff options
context:
space:
mode:
authorMichael Kruse <llvm-project@meinersbur.de>2025-01-03 10:22:51 +0100
committerMichael Kruse <llvm-project@meinersbur.de>2025-01-03 10:22:51 +0100
commit38500d63e14ce340236840f60d356cdefb56a52c (patch)
tree17edbec446ce9b50d2f215a483b83afb293a635d /libc/test/src/strings
parent1a3d5daaef7a6a63448a497da3eff7fc9e23df26 (diff)
parent27f30029741ecf023baece7b3dde1ff9011ffefc (diff)
Merge branch 'main' into users/meinersbur/flang_runtime_split-headersusers/meinersbur/flang_runtime_split-headers
Diffstat (limited to 'libc/test/src/strings')
-rw-r--r--libc/test/src/strings/CMakeLists.txt58
-rw-r--r--libc/test/src/strings/bcmp_test.cpp61
-rw-r--r--libc/test/src/strings/bcopy_test.cpp99
-rw-r--r--libc/test/src/strings/bzero_test.cpp30
-rw-r--r--libc/test/src/strings/index_test.cpp14
-rw-r--r--libc/test/src/strings/rindex_test.cpp14
-rw-r--r--libc/test/src/strings/strcasecmp_test.cpp46
-rw-r--r--libc/test/src/strings/strncasecmp_test.cpp48
8 files changed, 370 insertions, 0 deletions
diff --git a/libc/test/src/strings/CMakeLists.txt b/libc/test/src/strings/CMakeLists.txt
new file mode 100644
index 000000000000..10f96b8531f6
--- /dev/null
+++ b/libc/test/src/strings/CMakeLists.txt
@@ -0,0 +1,58 @@
+add_custom_target(libc-strings-tests)
+
+add_libc_test(
+ bcopy_test
+ SUITE
+ libc-strings-tests
+ SRCS
+ bcopy_test.cpp
+ DEPENDS
+ libc.src.strings.bcopy
+ LINK_LIBRARIES
+ LibcMemoryHelpers
+)
+
+add_libc_test(
+ index_test
+ SUITE
+ libc-strings-tests
+ SRCS
+ index_test.cpp
+ DEPENDS
+ libc.src.strings.index
+ libc.test.src.string.strchr_test_support
+)
+
+add_libc_test(
+ rindex_test
+ SUITE
+ libc-strings-tests
+ SRCS
+ rindex_test.cpp
+ DEPENDS
+ libc.src.strings.rindex
+ libc.test.src.string.strchr_test_support
+)
+
+add_libc_test(
+ strcasecmp_test
+ SUITE
+ libc-strings-tests
+ SRCS
+ strcasecmp_test.cpp
+ DEPENDS
+ libc.src.strings.strcasecmp
+)
+
+add_libc_test(
+ strncasecmp_test
+ SUITE
+ libc-strings-tests
+ SRCS
+ strncasecmp_test.cpp
+ DEPENDS
+ libc.src.strings.strncasecmp
+)
+
+add_libc_multi_impl_test(bcmp libc-strings-tests SRCS bcmp_test.cpp)
+add_libc_multi_impl_test(bzero libc-strings-tests SRCS bzero_test.cpp)
diff --git a/libc/test/src/strings/bcmp_test.cpp b/libc/test/src/strings/bcmp_test.cpp
new file mode 100644
index 000000000000..794f9a1b8bd9
--- /dev/null
+++ b/libc/test/src/strings/bcmp_test.cpp
@@ -0,0 +1,61 @@
+//===-- Unittests for bcmp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/macros/config.h"
+#include "src/strings/bcmp.h"
+#include "test/UnitTest/Test.h"
+#include "test/UnitTest/TestLogger.h"
+#include "test/src/string/memory_utils/memory_check_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+TEST(LlvmLibcBcmpTest, CmpZeroByte) {
+ const char *lhs = "ab";
+ const char *rhs = "bc";
+ ASSERT_EQ(LIBC_NAMESPACE::bcmp(lhs, rhs, 0), 0);
+}
+
+TEST(LlvmLibcBcmpTest, LhsRhsAreTheSame) {
+ const char *lhs = "ab";
+ const char *rhs = "ab";
+ ASSERT_EQ(LIBC_NAMESPACE::bcmp(lhs, rhs, 2), 0);
+}
+
+TEST(LlvmLibcBcmpTest, LhsBeforeRhsLexically) {
+ const char *lhs = "ab";
+ const char *rhs = "ac";
+ ASSERT_NE(LIBC_NAMESPACE::bcmp(lhs, rhs, 2), 0);
+}
+
+TEST(LlvmLibcBcmpTest, LhsAfterRhsLexically) {
+ const char *lhs = "ac";
+ const char *rhs = "ab";
+ ASSERT_NE(LIBC_NAMESPACE::bcmp(lhs, rhs, 2), 0);
+}
+
+// Adapt CheckBcmp signature to bcmp.
+static inline int Adaptor(cpp::span<char> p1, cpp::span<char> p2, size_t size) {
+ return LIBC_NAMESPACE::bcmp(p1.begin(), p2.begin(), size);
+}
+
+TEST(LlvmLibcBcmpTest, SizeSweep) {
+ static constexpr size_t kMaxSize = 400;
+ Buffer Buffer1(kMaxSize);
+ Buffer Buffer2(kMaxSize);
+ Randomize(Buffer1.span());
+ for (size_t size = 0; size < kMaxSize; ++size) {
+ auto span1 = Buffer1.span().subspan(0, size);
+ auto span2 = Buffer2.span().subspan(0, size);
+ const bool OK = CheckBcmp<Adaptor>(span1, span2, size);
+ if (!OK)
+ testing::tlog << "Failed at size=" << size << '\n';
+ ASSERT_TRUE(OK);
+ }
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/strings/bcopy_test.cpp b/libc/test/src/strings/bcopy_test.cpp
new file mode 100644
index 000000000000..f6bb859b4ae9
--- /dev/null
+++ b/libc/test/src/strings/bcopy_test.cpp
@@ -0,0 +1,99 @@
+//===-- Unittests for bcopy -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/strings/bcopy.h"
+
+#include "src/__support/CPP/span.h"
+#include "src/__support/macros/config.h"
+#include "test/UnitTest/MemoryMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/string/memory_utils/memory_check_utils.h"
+
+using LIBC_NAMESPACE::cpp::array;
+using LIBC_NAMESPACE::cpp::span;
+
+namespace LIBC_NAMESPACE_DECL {
+
+TEST(LlvmLibcBcopyTest, MoveZeroByte) {
+ char Buffer[] = {'a', 'b', 'y', 'z'};
+ const char Expected[] = {'a', 'b', 'y', 'z'};
+ void *const Dst = Buffer;
+ LIBC_NAMESPACE::bcopy(Buffer + 2, Dst, 0);
+ ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
+}
+
+TEST(LlvmLibcBcopyTest, DstAndSrcPointToSameAddress) {
+ char Buffer[] = {'a', 'b'};
+ const char Expected[] = {'a', 'b'};
+ void *const Dst = Buffer;
+ LIBC_NAMESPACE::bcopy(Buffer, Dst, 1);
+ ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
+}
+
+TEST(LlvmLibcBcopyTest, DstStartsBeforeSrc) {
+ // Set boundary at beginning and end for not overstepping when
+ // copy forward or backward.
+ char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
+ const char Expected[] = {'z', 'b', 'c', 'c', 'z'};
+ void *const Dst = Buffer + 1;
+ LIBC_NAMESPACE::bcopy(Buffer + 2, Dst, 2);
+ ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
+}
+
+TEST(LlvmLibcBcopyTest, DstStartsAfterSrc) {
+ char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
+ const char Expected[] = {'z', 'a', 'a', 'b', 'z'};
+ void *const Dst = Buffer + 2;
+ LIBC_NAMESPACE::bcopy(Buffer + 1, Dst, 2);
+ ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
+}
+
+// e.g. `Dst` follow `src`.
+// str: [abcdefghij]
+// [__src_____]
+// [_____Dst__]
+TEST(LlvmLibcBcopyTest, SrcFollowDst) {
+ char Buffer[] = {'z', 'a', 'b', 'z'};
+ const char Expected[] = {'z', 'b', 'b', 'z'};
+ void *const Dst = Buffer + 1;
+ LIBC_NAMESPACE::bcopy(Buffer + 2, Dst, 1);
+ ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
+}
+
+TEST(LlvmLibcBcopyTest, DstFollowSrc) {
+ char Buffer[] = {'z', 'a', 'b', 'z'};
+ const char Expected[] = {'z', 'a', 'a', 'z'};
+ void *const Dst = Buffer + 2;
+ LIBC_NAMESPACE::bcopy(Buffer + 1, Dst, 1);
+ ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
+}
+
+// Adapt CheckMemmove signature to bcopy.
+static inline void Adaptor(cpp::span<char> dst, cpp::span<char> src,
+ size_t size) {
+ LIBC_NAMESPACE::bcopy(src.begin(), dst.begin(), size);
+}
+
+TEST(LlvmLibcBcopyTest, SizeSweep) {
+ static constexpr int kMaxSize = 400;
+ static constexpr int kDenseOverlap = 15;
+ using LargeBuffer = array<char, 2 * kMaxSize + 1>;
+ LargeBuffer Buffer;
+ Randomize(Buffer);
+ for (int Size = 0; Size < kMaxSize; ++Size)
+ for (int Overlap = -1; Overlap < Size;) {
+ ASSERT_TRUE(CheckMemmove<Adaptor>(Buffer, Size, Overlap));
+ // Prevent quadratic behavior by skipping offset above kDenseOverlap.
+ if (Overlap > kDenseOverlap)
+ Overlap *= 2;
+ else
+ ++Overlap;
+ }
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/strings/bzero_test.cpp b/libc/test/src/strings/bzero_test.cpp
new file mode 100644
index 000000000000..4d4112f4be8e
--- /dev/null
+++ b/libc/test/src/strings/bzero_test.cpp
@@ -0,0 +1,30 @@
+//===-- Unittests for bzero -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/macros/config.h"
+#include "src/strings/bzero.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/string/memory_utils/memory_check_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// Adapt CheckMemset signature to bzero.
+static inline void Adaptor(cpp::span<char> p1, uint8_t value, size_t size) {
+ LIBC_NAMESPACE::bzero(p1.begin(), size);
+}
+
+TEST(LlvmLibcBzeroTest, SizeSweep) {
+ static constexpr size_t kMaxSize = 400;
+ Buffer DstBuffer(kMaxSize);
+ for (size_t size = 0; size < kMaxSize; ++size) {
+ auto dst = DstBuffer.span().subspan(0, size);
+ ASSERT_TRUE((CheckMemset<Adaptor>(dst, 0, size)));
+ }
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/strings/index_test.cpp b/libc/test/src/strings/index_test.cpp
new file mode 100644
index 000000000000..fc4cd2b31c55
--- /dev/null
+++ b/libc/test/src/strings/index_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for index -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "test/src/string/StrchrTest.h"
+
+#include "src/strings/index.h"
+#include "test/UnitTest/Test.h"
+
+STRCHR_TEST(Index, LIBC_NAMESPACE::index)
diff --git a/libc/test/src/strings/rindex_test.cpp b/libc/test/src/strings/rindex_test.cpp
new file mode 100644
index 000000000000..d3b756fe5f6e
--- /dev/null
+++ b/libc/test/src/strings/rindex_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for rindex ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "test/src/string/StrchrTest.h"
+
+#include "src/strings/rindex.h"
+#include "test/UnitTest/Test.h"
+
+STRRCHR_TEST(Rindex, LIBC_NAMESPACE::rindex)
diff --git a/libc/test/src/strings/strcasecmp_test.cpp b/libc/test/src/strings/strcasecmp_test.cpp
new file mode 100644
index 000000000000..cd29c213a732
--- /dev/null
+++ b/libc/test/src/strings/strcasecmp_test.cpp
@@ -0,0 +1,46 @@
+//===-- Unittests for strcasecmp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/strings/strcasecmp.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStrCaseCmpTest, EmptyStringsShouldReturnZero) {
+ const char *s1 = "";
+ const char *s2 = "";
+ int result = LIBC_NAMESPACE::strcasecmp(s1, s2);
+ ASSERT_EQ(result, 0);
+
+ // Verify operands reversed.
+ result = LIBC_NAMESPACE::strcasecmp(s2, s1);
+ ASSERT_EQ(result, 0);
+}
+
+TEST(LlvmLibcStrCaseCmpTest, EmptyStringShouldNotEqualNonEmptyString) {
+ const char *empty = "";
+ const char *s2 = "abc";
+ int result = LIBC_NAMESPACE::strcasecmp(empty, s2);
+ // This should be '\0' - 'a' = -97
+ ASSERT_LT(result, 0);
+
+ // Similar case if empty string is second argument.
+ const char *s3 = "123";
+ result = LIBC_NAMESPACE::strcasecmp(s3, empty);
+ // This should be '1' - '\0' = 49
+ ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcStrCaseCmpTest, Case) {
+ const char *s1 = "aB";
+ const char *s2 = "ab";
+ int result = LIBC_NAMESPACE::strcasecmp(s1, s2);
+ ASSERT_EQ(result, 0);
+
+ // Verify operands reversed.
+ result = LIBC_NAMESPACE::strcasecmp(s2, s1);
+ ASSERT_EQ(result, 0);
+}
diff --git a/libc/test/src/strings/strncasecmp_test.cpp b/libc/test/src/strings/strncasecmp_test.cpp
new file mode 100644
index 000000000000..870574ed9507
--- /dev/null
+++ b/libc/test/src/strings/strncasecmp_test.cpp
@@ -0,0 +1,48 @@
+//===-- Unittests for strncasecmp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/strings/strncasecmp.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcStrNCaseCmpTest,
+ EmptyStringsShouldReturnZeroWithSufficientLength) {
+ const char *s1 = "";
+ const char *s2 = "";
+ int result = LIBC_NAMESPACE::strncasecmp(s1, s2, 1);
+ ASSERT_EQ(result, 0);
+
+ // Verify operands reversed.
+ result = LIBC_NAMESPACE::strncasecmp(s2, s1, 1);
+ ASSERT_EQ(result, 0);
+}
+
+TEST(LlvmLibcStrNCaseCmpTest,
+ EmptyStringShouldNotEqualNonEmptyStringWithSufficientLength) {
+ const char *empty = "";
+ const char *s2 = "abc";
+ int result = LIBC_NAMESPACE::strncasecmp(empty, s2, 3);
+ // This should be '\0' - 'a' = -97
+ ASSERT_LT(result, 0);
+
+ // Similar case if empty string is second argument.
+ const char *s3 = "123";
+ result = LIBC_NAMESPACE::strncasecmp(s3, empty, 3);
+ // This should be '1' - '\0' = 49
+ ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcStrNCaseCmpTest, Case) {
+ const char *s1 = "aB";
+ const char *s2 = "ab";
+ int result = LIBC_NAMESPACE::strncasecmp(s1, s2, 2);
+ ASSERT_EQ(result, 0);
+
+ // Verify operands reversed.
+ result = LIBC_NAMESPACE::strncasecmp(s2, s1, 2);
+ ASSERT_EQ(result, 0);
+}