diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt index d8f78f0d1745..706f603b6ff5 100644 --- a/libc/config/gpu/entrypoints.txt +++ b/libc/config/gpu/entrypoints.txt @@ -58,6 +58,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strchrnul libc.src.string.strcmp libc.src.string.strcoll + libc.src.string.strcoll_l libc.src.string.strcpy libc.src.string.strcspn libc.src.string.strdup @@ -79,6 +80,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strtok libc.src.string.strtok_r libc.src.string.strxfrm + libc.src.string.strxfrm_l # stdbit.h entrypoints libc.src.stdbit.stdc_bit_ceil_uc diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 0aa38c7afc76..3fd88fc0020e 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -809,6 +809,10 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.stdlib.strtoul_l libc.src.stdlib.strtoull_l + # string.h entrypoints + libc.src.string.strcoll_l + libc.src.string.strxfrm_l + # assert.h entrypoints libc.src.assert.__assert_fail diff --git a/libc/include/string.h.def b/libc/include/string.h.def index 1bd2687db2be..e180f0d2561d 100644 --- a/libc/include/string.h.def +++ b/libc/include/string.h.def @@ -11,6 +11,7 @@ #include "__llvm-libc-common.h" +#include "llvm-libc-types/locale_t.h" #include "llvm-libc-macros/null-macro.h" %%public_api() diff --git a/libc/newhdrgen/yaml/string.yaml b/libc/newhdrgen/yaml/string.yaml index 1d6e64bfb9cf..af1750e91243 100644 --- a/libc/newhdrgen/yaml/string.yaml +++ b/libc/newhdrgen/yaml/string.yaml @@ -144,6 +144,14 @@ functions: arguments: - type: const char * - type: const char * + - name: strcoll_l + standards: + - stdc + return_type: int + arguments: + - type: const char * + - type: const char * + - type: locale_t - name: strcpy standards: - stdc @@ -300,3 +308,12 @@ functions: - type: char *__restrict - type: const char *__restrict - type: size_t + - name: strxfrm_l + standards: + - stdc + return_type: size_t + arguments: + - type: char *__restrict + - type: const char *__restrict + - type: size_t + - type: locale_t diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 2c61cb9d9529..1742e1f7b0ef 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -354,6 +354,11 @@ def StdC : StandardSpec<"stdc"> { RetValSpec, [ArgSpec, ArgSpec] >, + FunctionSpec< + "strcoll_l", + RetValSpec, + [ArgSpec, ArgSpec, ArgSpec] + >, FunctionSpec< "strncmp", RetValSpec, @@ -366,6 +371,14 @@ def StdC : StandardSpec<"stdc"> { ArgSpec, ArgSpec] >, + FunctionSpec< + "strxfrm_l", + RetValSpec, + [ArgSpec, + ArgSpec, + ArgSpec, + ArgSpec] + >, FunctionSpec< "strchr", RetValSpec, diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt index 56588ffafb86..787188ab3beb 100644 --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -200,6 +200,14 @@ add_entrypoint_object( strcoll.h ) +add_entrypoint_object( + strcoll_l + SRCS + strcoll_l.cpp + HDRS + strcoll_l.h +) + add_entrypoint_object( strcpy SRCS @@ -441,6 +449,17 @@ add_entrypoint_object( .memory_utils.inline_memcpy ) +add_entrypoint_object( + strxfrm_l + SRCS + strxfrm_l.cpp + HDRS + strxfrm_l.h + DEPENDS + .string_utils + .memory_utils.inline_memcpy +) + add_entrypoint_object( memset_explicit SRCS diff --git a/libc/src/string/strcoll_l.cpp b/libc/src/string/strcoll_l.cpp new file mode 100644 index 000000000000..f664a3c7c03f --- /dev/null +++ b/libc/src/string/strcoll_l.cpp @@ -0,0 +1,24 @@ +//===-- Implementation of strcoll_l ---------------------------------------===// +// +// 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_l.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +// TODO: Add support for locales. +LLVM_LIBC_FUNCTION(int, strcoll_l, + (const char *left, const char *right, locale_t)) { + for (; *left && *left == *right; ++left, ++right) + ; + return static_cast(*left) - static_cast(*right); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/string/strcoll_l.h b/libc/src/string/strcoll_l.h new file mode 100644 index 000000000000..97230fb81123 --- /dev/null +++ b/libc/src/string/strcoll_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for strcoll_l ---------------------*- 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_L_H +#define LLVM_LIBC_SRC_STRING_STRCOLL_L_H + +#include "include/llvm-libc-types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int strcoll_l(const char *left, const char *right, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STRING_STRCOLL_L_H diff --git a/libc/src/string/strxfrm_l.cpp b/libc/src/string/strxfrm_l.cpp new file mode 100644 index 000000000000..ae758e1fcba6 --- /dev/null +++ b/libc/src/string/strxfrm_l.cpp @@ -0,0 +1,28 @@ +//===-- Implementation of strxfrm_l ---------------------------------------===// +// +// 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/strxfrm_l.h" +#include "src/__support/macros/config.h" +#include "src/string/memory_utils/inline_memcpy.h" +#include "src/string/string_utils.h" + +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE_DECL { + +// TODO: Add support for locales. +LLVM_LIBC_FUNCTION(size_t, strxfrm_l, + (char *__restrict dest, const char *__restrict src, size_t n, + locale_t)) { + size_t len = internal::string_length(src); + if (n > len) + inline_memcpy(dest, src, len + 1); + return len; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/string/strxfrm_l.h b/libc/src/string/strxfrm_l.h new file mode 100644 index 000000000000..af0f18160118 --- /dev/null +++ b/libc/src/string/strxfrm_l.h @@ -0,0 +1,23 @@ +//===-- Implementation header for strxfrm_l ---------------------*- 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_STRXFRM_L_H +#define LLVM_LIBC_SRC_STRING_STRXFRM_L_H + +#include "include/llvm-libc-types/locale_t.h" +#include "src/__support/macros/config.h" +#include // For size_t + +namespace LIBC_NAMESPACE_DECL { + +size_t strxfrm_l(char *__restrict dest, const char *__restrict src, size_t n, + locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STRING_STRXFRM_L_H