diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -42,6 +42,7 @@ libc.src.string.strcat libc.src.string.strchr libc.src.string.strcmp + libc.src.string.strcoll libc.src.string.strcpy libc.src.string.strcspn libc.src.string.strdup diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -96,6 +96,14 @@ strcmp.h ) +add_entrypoint_object( + strcoll + SRCS + strcoll.cpp + HDRS + strcoll.h +) + add_entrypoint_object( strcpy SRCS diff --git a/libc/src/string/strcoll.h b/libc/src/string/strcoll.h new file mode 100644 --- /dev/null +++ b/libc/src/string/strcoll.h @@ -0,0 +1,18 @@ +//===-- Implementation header for strcoll -----------------------*- 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_STRCOLL_H +#define LLVM_LIBC_SRC_STRING_STRCOLL_H + +namespace __llvm_libc { + +int strcoll(const char *left, const char *right); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STRING_STRCOLL_H diff --git a/libc/src/string/strcoll.cpp b/libc/src/string/strcoll.cpp new file mode 100644 --- /dev/null +++ b/libc/src/string/strcoll.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of strcoll -----------------------------------------===// +// +// 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/strcoll.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +// TODO: Add support for locales. +LLVM_LIBC_FUNCTION(int, strcoll, (const char *left, const char *right)) { + for (; *left && *left == *right; ++left, ++right) + ; + return static_cast(*left) - static_cast(*right); +} + +} // namespace __llvm_libc diff --git a/libc/test/src/string/CMakeLists.txt b/libc/test/src/string/CMakeLists.txt --- a/libc/test/src/string/CMakeLists.txt +++ b/libc/test/src/string/CMakeLists.txt @@ -92,6 +92,16 @@ libc.src.string.strcmp ) +add_libc_unittest( + strcoll_test + SUITE + libc_string_unittests + SRCS + strcoll_test.cpp + DEPENDS + libc.src.string.strcoll +) + add_libc_unittest( strcpy_test SUITE diff --git a/libc/test/src/string/strcoll_test.cpp b/libc/test/src/string/strcoll_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/string/strcoll_test.cpp @@ -0,0 +1,30 @@ +//===-- Unittests for strcoll ---------------------------------------------===// +// +// 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/strcoll.h" +#include "utils/UnitTest/Test.h" + +// TODO: Add more comprehensive tests once locale support is added. + +TEST(LlvmLibcStrcollTest, SimpleTest) { + const char *s1 = "abc"; + const char *s2 = "abc"; + const char *s3 = "def"; + int result = __llvm_libc::strcoll(s1, s2); + ASSERT_EQ(result, 0); + + // Verify operands reversed. + result = __llvm_libc::strcoll(s2, s1); + ASSERT_EQ(result, 0); + + result = __llvm_libc::strcoll(s1, s3); + ASSERT_LT(result, 0); + + result = __llvm_libc::strcoll(s3, s1); + ASSERT_GT(result, 0); +}