[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