[libc-commits] [libc] 05e1612 - [libc] This adds the strcmp (string compare) implementation.
via libc-commits
libc-commits at lists.llvm.org
Fri Jun 19 13:12:13 PDT 2020
Author: cgyurgyik
Date: 2020-06-19T16:09:44-04:00
New Revision: 05e1612c4345353680752bad23eb52eba3ab51a3
URL: https://github.com/llvm/llvm-project/commit/05e1612c4345353680752bad23eb52eba3ab51a3
DIFF: https://github.com/llvm/llvm-project/commit/05e1612c4345353680752bad23eb52eba3ab51a3.diff
LOG: [libc] This adds the strcmp (string compare) implementation.
Reviewed-by: sivachandra
Differential Revision: https://reviews.llvm.org/D82134
Added:
libc/src/string/strcmp.cpp
libc/src/string/strcmp.h
libc/test/src/string/strcmp_test.cpp
Modified:
libc/config/linux/x86_64/entrypoints.txt
libc/src/string/CMakeLists.txt
libc/test/src/string/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 656ccddfeedf..a7836636c819 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -26,6 +26,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strcpy
libc.src.string.strcat
libc.src.string.strlen
+ libc.src.string.strcmp
# sys/mman.h entrypoints
libc.src.sys.mman.mmap
diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index dee547bc860d..51456e8a94c8 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -34,6 +34,16 @@ add_entrypoint_object(
libc.include.string
)
+add_entrypoint_object(
+ strcmp
+ SRCS
+ strcmp.cpp
+ HDRS
+ strcmp.h
+ DEPENDS
+ libc.include.string
+)
+
# Helper to define a function with multiple implementations
# - Computes flags to satisfy required/rejected features and arch,
# - Declares an entry point,
diff --git a/libc/src/string/strcmp.cpp b/libc/src/string/strcmp.cpp
new file mode 100644
index 000000000000..4ef7a77363e5
--- /dev/null
+++ b/libc/src/string/strcmp.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of strcmp ------------------------------------------===//
+//
+// 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/string/strcmp.h"
+
+#include "src/__support/common.h"
+
+namespace __llvm_libc {
+
+// TODO: Look at benefits for comparing words at a time.
+int LLVM_LIBC_ENTRYPOINT(strcmp)(const char *left, const char *right) {
+ for (; *left && *left == *right; ++left, ++right)
+ ;
+ return *reinterpret_cast<const unsigned char *>(left) -
+ *reinterpret_cast<const unsigned char *>(right);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/string/strcmp.h b/libc/src/string/strcmp.h
new file mode 100644
index 000000000000..a45f2d5ba8e5
--- /dev/null
+++ b/libc/src/string/strcmp.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for strcmp ------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STRING_STRCMP_H
+#define LLVM_LIBC_SRC_STRING_STRCMP_H
+
+namespace __llvm_libc {
+
+int strcmp(const char *left, const char *right);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STRING_STRCMP_H
diff --git a/libc/test/src/string/CMakeLists.txt b/libc/test/src/string/CMakeLists.txt
index abe06528eeb6..992cebe5067c 100644
--- a/libc/test/src/string/CMakeLists.txt
+++ b/libc/test/src/string/CMakeLists.txt
@@ -32,6 +32,16 @@ add_libc_unittest(
libc.src.string.strlen
)
+add_libc_unittest(
+ strcmp_test
+ SUITE
+ libc_string_unittests
+ SRCS
+ strcmp_test.cpp
+ DEPENDS
+ libc.src.string.strcmp
+)
+
# Tests all implementations that can run on the host.
function(add_libc_multi_impl_test name)
get_property(fq_implementations GLOBAL PROPERTY ${name}_implementations)
diff --git a/libc/test/src/string/strcmp_test.cpp b/libc/test/src/string/strcmp_test.cpp
new file mode 100644
index 000000000000..18e20a2b5637
--- /dev/null
+++ b/libc/test/src/string/strcmp_test.cpp
@@ -0,0 +1,97 @@
+//===-- Unittests for strcmp ----------------------------------------------===//
+//
+// 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/string/strcmp.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(StrCmpTest, EmptyStringsShouldReturnZero) {
+ const char *s1 = "";
+ const char *s2 = "";
+ int result = __llvm_libc::strcmp(s1, s2);
+ ASSERT_EQ(result, 0);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strcmp(s2, s1);
+ ASSERT_EQ(result, 0);
+}
+
+TEST(StrCmpTest, EmptyStringShouldNotEqualNonEmptyString) {
+ const char *empty = "";
+ const char *s2 = "abc";
+ int result = __llvm_libc::strcmp(empty, s2);
+ // This should be '\0' - 'a' = -97
+ ASSERT_EQ(result, -97);
+
+ // Similar case if empty string is second argument.
+ const char *s3 = "123";
+ result = __llvm_libc::strcmp(s3, empty);
+ // This should be '1' - '\0' = 49
+ ASSERT_EQ(result, 49);
+}
+
+TEST(StrCmpTest, EqualStringsShouldReturnZero) {
+ const char *s1 = "abc";
+ const char *s2 = "abc";
+ int result = __llvm_libc::strcmp(s1, s2);
+ ASSERT_EQ(result, 0);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strcmp(s2, s1);
+ ASSERT_EQ(result, 0);
+}
+
+TEST(StrCmpTest, ShouldReturnResultOfFirstDifference) {
+ const char *s1 = "___B42__";
+ const char *s2 = "___C55__";
+ int result = __llvm_libc::strcmp(s1, s2);
+ // This should return 'B' - 'C' = -1.
+ ASSERT_EQ(result, -1);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strcmp(s2, s1);
+ // This should return 'C' - 'B' = 1.
+ ASSERT_EQ(result, 1);
+}
+
+TEST(StrCmpTest, CapitalizedLetterShouldNotBeEqual) {
+ const char *s1 = "abcd";
+ const char *s2 = "abCd";
+ int result = __llvm_libc::strcmp(s1, s2);
+ // 'c' - 'C' = 32.
+ ASSERT_EQ(result, 32);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strcmp(s2, s1);
+ // 'C' - 'c' = -32.
+ ASSERT_EQ(result, -32);
+}
+
+TEST(StrCmpTest, UnequalLengthStringsShouldNotReturnZero) {
+ const char *s1 = "abc";
+ const char *s2 = "abcd";
+ int result = __llvm_libc::strcmp(s1, s2);
+ // '\0' - 'd' = -100.
+ ASSERT_EQ(result, -100);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strcmp(s2, s1);
+ // 'd' - '\0' = 100.
+ ASSERT_EQ(result, 100);
+}
+
+TEST(StrCmpTest, StringArgumentSwapChangesSign) {
+ const char *a = "a";
+ const char *b = "b";
+ int result = __llvm_libc::strcmp(b, a);
+ // 'b' - 'a' = 1.
+ ASSERT_EQ(result, 1);
+
+ result = __llvm_libc::strcmp(a, b);
+ // 'a' - 'b' = -1.
+ ASSERT_EQ(result, -1);
+}
More information about the libc-commits
mailing list