[libc] This adds the strcmp (string compare) implementation.
Reviewed-by: sivachandra Differential Revision: https://reviews.llvm.org/D82134
This commit is contained in:
parent
af4f2eb476
commit
05e1612c43
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue