From ae64d6a8be81aefb84837eff9ea0e51cfabc18c9 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Fri, 9 Aug 2024 11:00:00 -0500 Subject: [PATCH 1/2] [libc] Initial support for 'locale.h' in the LLVM libc Summary: This patch adds the macros and entrypoints associated with the `locale.h` entrypoints. These are mostly stubs, as we (for now and the forseeable future) only expect to support the C and maybe C.UTF-8 locales in the LLVM libc. --- libc/config/gpu/entrypoints.txt | 9 +++ libc/config/gpu/headers.txt | 1 + libc/config/linux/x86_64/entrypoints.txt | 9 +++ libc/config/linux/x86_64/headers.txt | 1 + libc/hdr/types/CMakeLists.txt | 9 +++ libc/hdr/types/locale_t.h | 22 ++++++ libc/include/CMakeLists.txt | 12 +++ libc/include/llvm-libc-macros/CMakeLists.txt | 6 ++ libc/include/llvm-libc-macros/locale-macros.h | 32 ++++++++ libc/include/llvm-libc-types/CMakeLists.txt | 2 + libc/include/llvm-libc-types/locale_t.h | 22 ++++++ libc/include/llvm-libc-types/struct_lconv.h | 39 ++++++++++ libc/include/locale.h.def | 20 +++++ libc/newhdrgen/yaml/locale.yaml | 41 ++++++++++ libc/spec/stdc.td | 57 ++++++++++++++ libc/src/CMakeLists.txt | 1 + libc/src/locale/CMakeLists.txt | 76 +++++++++++++++++++ libc/src/locale/duplocale.cpp | 21 +++++ libc/src/locale/duplocale.h | 22 ++++++ libc/src/locale/freelocale.cpp | 21 +++++ libc/src/locale/freelocale.h | 22 ++++++ libc/src/locale/locale.cpp | 21 +++++ libc/src/locale/locale.h | 36 +++++++++ libc/src/locale/localeconv.cpp | 49 ++++++++++++ libc/src/locale/localeconv.h | 22 ++++++ libc/src/locale/newlocale.cpp | 28 +++++++ libc/src/locale/newlocale.h | 22 ++++++ libc/src/locale/setlocale.cpp | 28 +++++++ libc/src/locale/setlocale.h | 22 ++++++ libc/src/locale/uselocale.cpp | 23 ++++++ libc/src/locale/uselocale.h | 22 ++++++ libc/test/src/CMakeLists.txt | 1 + libc/test/src/locale/CMakeLists.txt | 25 ++++++ libc/test/src/locale/locale_test.cpp | 27 +++++++ libc/test/src/locale/localeconv_test.cpp | 17 +++++ 35 files changed, 788 insertions(+) create mode 100644 libc/hdr/types/locale_t.h create mode 100644 libc/include/llvm-libc-macros/locale-macros.h create mode 100644 libc/include/llvm-libc-types/locale_t.h create mode 100644 libc/include/llvm-libc-types/struct_lconv.h create mode 100644 libc/include/locale.h.def create mode 100644 libc/newhdrgen/yaml/locale.yaml create mode 100644 libc/src/locale/CMakeLists.txt create mode 100644 libc/src/locale/duplocale.cpp create mode 100644 libc/src/locale/duplocale.h create mode 100644 libc/src/locale/freelocale.cpp create mode 100644 libc/src/locale/freelocale.h create mode 100644 libc/src/locale/locale.cpp create mode 100644 libc/src/locale/locale.h create mode 100644 libc/src/locale/localeconv.cpp create mode 100644 libc/src/locale/localeconv.h create mode 100644 libc/src/locale/newlocale.cpp create mode 100644 libc/src/locale/newlocale.h create mode 100644 libc/src/locale/setlocale.cpp create mode 100644 libc/src/locale/setlocale.h create mode 100644 libc/src/locale/uselocale.cpp create mode 100644 libc/src/locale/uselocale.h create mode 100644 libc/test/src/locale/CMakeLists.txt create mode 100644 libc/test/src/locale/locale_test.cpp create mode 100644 libc/test/src/locale/localeconv_test.cpp diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt index b2644d2ebf386..592c8cdb7ae77 100644 --- a/libc/config/gpu/entrypoints.txt +++ b/libc/config/gpu/entrypoints.txt @@ -231,6 +231,15 @@ set(TARGET_LIBC_ENTRYPOINTS # wchar.h entrypoints libc.src.wchar.wctob + # locale.h entrypoints + libc.src.locale.localeconv + libc.src.locale.duplocale + libc.src.locale.freelocale + libc.src.locale.localeconv + libc.src.locale.newlocale + libc.src.locale.setlocale + libc.src.locale.uselocale + # gpu/rpc.h entrypoints libc.src.gpu.rpc_host_call ) diff --git a/libc/config/gpu/headers.txt b/libc/config/gpu/headers.txt index 99280b7563a80..fc952c40f4daa 100644 --- a/libc/config/gpu/headers.txt +++ b/libc/config/gpu/headers.txt @@ -16,6 +16,7 @@ set(TARGET_PUBLIC_HEADERS libc.include.wchar libc.include.uchar libc.include.features + libc.include.locale # Header for RPC extensions libc.include.gpu_rpc diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 65c5757efe627..e7c3c7db64abe 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -982,6 +982,15 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.time.nanosleep libc.src.time.time + # locale.h entrypoints + libc.src.locale.localeconv + libc.src.locale.duplocale + libc.src.locale.freelocale + libc.src.locale.localeconv + libc.src.locale.newlocale + libc.src.locale.setlocale + libc.src.locale.uselocale + # unistd.h entrypoints libc.src.unistd.__llvm_libc_syscall libc.src.unistd._exit diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt index 77e454e64395d..881e149d9c40d 100644 --- a/libc/config/linux/x86_64/headers.txt +++ b/libc/config/linux/x86_64/headers.txt @@ -33,6 +33,7 @@ set(TARGET_PUBLIC_HEADERS libc.include.unistd libc.include.wchar libc.include.uchar + libc.include.locale libc.include.arpa_inet diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt index 4fc28fd82e68d..f41576c07d99b 100644 --- a/libc/hdr/types/CMakeLists.txt +++ b/libc/hdr/types/CMakeLists.txt @@ -162,3 +162,12 @@ add_proxy_header_library( libc.include.llvm-libc-types.cookie_io_functions_t libc.include.stdio ) + +add_proxy_header_library( + locale_t + HDRS + locale_t.h + FULL_BUILD_DEPENDS + libc.include.llvm-libc-types.locale_t + libc.include.locale +) diff --git a/libc/hdr/types/locale_t.h b/libc/hdr/types/locale_t.h new file mode 100644 index 0000000000000..485258b461696 --- /dev/null +++ b/libc/hdr/types/locale_t.h @@ -0,0 +1,22 @@ +//===-- Definition of macros from locale_t.h ------------------------------===// +// +// 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_HDR_LOCALE_T_H +#define LLVM_LIBC_HDR_LOCALE_T_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-types/locale_t.h" + +#else // overlay mode + +#error "type not available in overlay mode" + +#endif // LLVM_LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_LOCALE_T_H diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index 2b6eb61782a63..733582c182735 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -717,6 +717,18 @@ add_header_macro( .llvm-libc-types.wchar_t ) +add_header_macro( + locale + ../libc/newhdrgen/yaml/locale.yaml + locale.h.def + locale.h + DEPENDS + .llvm_libc_common_h + .llvm-libc-macros.locale_macros + .llvm-libc-types.locale_t + .llvm-libc-types.struct_lconv +) + if(LIBC_TARGET_OS_IS_GPU) file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/gpu) diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt index 60a8725f9ef63..7b980232ba042 100644 --- a/libc/include/llvm-libc-macros/CMakeLists.txt +++ b/libc/include/llvm-libc-macros/CMakeLists.txt @@ -295,3 +295,9 @@ add_macro_header( HDR elf-macros.h ) + +add_macro_header( + locale_macros + HDR + locale-macros.h +) diff --git a/libc/include/llvm-libc-macros/locale-macros.h b/libc/include/llvm-libc-macros/locale-macros.h new file mode 100644 index 0000000000000..892f8b69f3a77 --- /dev/null +++ b/libc/include/llvm-libc-macros/locale-macros.h @@ -0,0 +1,32 @@ +//===-- Definition of macros from locale.h --------------------------------===// +// +// 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_MACROS_LOCALE_MACROS_H +#define LLVM_LIBC_MACROS_LOCALE_MACROS_H + +#include "../llvm-libc-types/locale_t.h" + +#define LC_CTYPE 0 +#define LC_NUMERIC 1 +#define LC_TIME 2 +#define LC_COLLATE 3 +#define LC_MONETARY 4 +#define LC_MESSAGES 5 +#define LC_ALL 6 + +#define LC_GLOBAL_LOCALE ((locale_t)(-1)) + +#define LC_CTYPE_MASK (1 << LC_CTYPE) +#define LC_NUMERIC_MASK (1 << LC_NUMERIC) +#define LC_TIME_MASK (1 << LC_TIME) +#define LC_COLLATE_MASK (1 << LC_COLLATE) +#define LC_MONETARY_MASK (1 << LC_MONETARY) +#define LC_MESSAGES_MASK (1 << LC_MESSAGES) +#define LC_ALL_MASK 0x7fffffff + +#endif // LLVM_LIBC_MACROS_LOCALE_MACROS_H diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index 0fa86e0152f9b..583b84ccaae67 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -142,3 +142,5 @@ DEPENDS .fsblkcnt_t .fsfilcnt_t ) +add_header(locale_t HDR locale_t.h) +add_header(struct_lconv HDR struct_lconv.h) diff --git a/libc/include/llvm-libc-types/locale_t.h b/libc/include/llvm-libc-types/locale_t.h new file mode 100644 index 0000000000000..6d783001acf9f --- /dev/null +++ b/libc/include/llvm-libc-types/locale_t.h @@ -0,0 +1,22 @@ +//===-- Definition of type locale_t ---------------------------------------===// +// +// 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_TYPES_LOCALE_T_H +#define LLVM_LIBC_TYPES_LOCALE_T_H + +#define NUM_LOCALE_CATEGORIES 6 + +struct __locale_data; + +struct __locale_t { + struct __locale_data *data[NUM_LOCALE_CATEGORIES]; +}; + +typedef struct __locale_t *locale_t; + +#endif // LLVM_LIBC_TYPES_LOCALE_T_H diff --git a/libc/include/llvm-libc-types/struct_lconv.h b/libc/include/llvm-libc-types/struct_lconv.h new file mode 100644 index 0000000000000..9d69f055484da --- /dev/null +++ b/libc/include/llvm-libc-types/struct_lconv.h @@ -0,0 +1,39 @@ +//===-- Definition of type lconv ------------------------------------------===// +// +// 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_TYPES_LCONV_H +#define LLVM_LIBC_TYPES_LCONV_H + +struct lconv { + char *decimal_point; + char *thousands_sep; + char *grouping; + char *mon_decimal_point; + char *mon_thousands_sep; + char *mon_grouping; + char *positive_sign; + char *negative_sign; + char *currency_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char *int_curr_symbol; + char int_frac_digits; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; + +#endif // LLVM_LIBC_TYPES_LCONV_H diff --git a/libc/include/locale.h.def b/libc/include/locale.h.def new file mode 100644 index 0000000000000..516c6e6275e68 --- /dev/null +++ b/libc/include/locale.h.def @@ -0,0 +1,20 @@ +//===-- C standard library header locale.h --------------------------------===// +// +// 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_LOCALE_H +#define LLVM_LIBC_LOCALE_H + +#include "__llvm-libc-common.h" + +#include "llvm-libc-macros/locale-macros.h" +#include "llvm-libc-types/locale_t.h" +#include "llvm-libc-types/struct_lconv.h" + +%%public_api() + +#endif // LLVM_LIBC_LOCALE_H diff --git a/libc/newhdrgen/yaml/locale.yaml b/libc/newhdrgen/yaml/locale.yaml new file mode 100644 index 0000000000000..7da7966ea730f --- /dev/null +++ b/libc/newhdrgen/yaml/locale.yaml @@ -0,0 +1,41 @@ +header: locale.h +functions: + - name: localeconv + standards: + - stdc + return_type: struct lconv * + arguments: + - type: void + - name: duplocale + standards: + - stdc + return_type: locale_t + arguments: + - type: locale_t + - name: freelocale + standards: + - stdc + return_type: void + arguments: + - type: locale_t + - name: newlocale + standards: + - stdc + return_type: locale_t + arguments: + - type: int + - type: const char * + - type: locale_t + - name: setlocale + standards: + - stdc + return_type: char * + arguments: + - type: int + - type: const char * + - name: uselocale + standards: + - stdc + return_type: locale_t + arguments: + - type: locale_t diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index e06a4f9b268e6..76a9ed123356a 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -4,6 +4,7 @@ def StdC : StandardSpec<"stdc"> { PtrType StructTmPtr = PtrType; PtrType TimeTTypePtr = PtrType; NamedType ClockT = NamedType<"clock_t">; + NamedType LocaleT = NamedType<"locale_t">; NamedType DivTType = NamedType<"div_t">; NamedType LDivTType = NamedType<"ldiv_t">; @@ -1588,6 +1589,61 @@ def StdC : StandardSpec<"stdc"> { ] >; + + NamedType StructLconv : NamedType<"struct lconv">; + PtrType StructLconvPtr : PtrType; + + HeaderSpec Locale = HeaderSpec< + "locale.h", + [], // Macros + [LocaleT, StructLconv], // Types + [], // Enumerations + [ + FunctionSpec< + "duplocale", + RetValSpec, + [ + ArgSpec + ] + >, + FunctionSpec< + "freelocale", + RetValSpec, + [ + ArgSpec + ] + >, + FunctionSpec< + "localeconv", + RetValSpec, + [] + >, + FunctionSpec< + "newlocale", + RetValSpec, + [ + ArgSpec, + ArgSpec, + ArgSpec + ] + >, + FunctionSpec< + "setlocale", + RetValSpec, + [ + ArgSpec, + ArgSpec + ] + >, + FunctionSpec< + "uselocale", + RetValSpec, + [ + ArgSpec + ] + > + ] // Functions + >; let Headers = [ Assert, @@ -1610,5 +1666,6 @@ def StdC : StandardSpec<"stdc"> { Time, UChar, WChar, + Locale, ]; } diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt index 9597e2380172b..d554c12fb1ec8 100644 --- a/libc/src/CMakeLists.txt +++ b/libc/src/CMakeLists.txt @@ -40,3 +40,4 @@ add_subdirectory(signal) add_subdirectory(spawn) add_subdirectory(threads) add_subdirectory(time) +add_subdirectory(locale) diff --git a/libc/src/locale/CMakeLists.txt b/libc/src/locale/CMakeLists.txt new file mode 100644 index 0000000000000..6aaeb2ac31488 --- /dev/null +++ b/libc/src/locale/CMakeLists.txt @@ -0,0 +1,76 @@ +add_object_library( + locale + SRCS + locale.cpp + HDRS + locale.h + DEPENDS + libc.include.locale +) + +add_entrypoint_object( + localeconv + SRCS + localeconv.cpp + HDRS + localeconv.h + DEPENDS + libc.include.locale + CXX_STANDARD + 20 # For designated initializers +) + +add_entrypoint_object( + newlocale + SRCS + newlocale.cpp + HDRS + newlocale.h + DEPENDS + libc.include.locale + .locale +) + +add_entrypoint_object( + duplocale + SRCS + duplocale.cpp + HDRS + duplocale.h + DEPENDS + libc.include.locale + .locale +) + +add_entrypoint_object( + setlocale + SRCS + setlocale.cpp + HDRS + setlocale.h + DEPENDS + libc.include.locale + .locale +) + +add_entrypoint_object( + uselocale + SRCS + uselocale.cpp + HDRS + uselocale.h + DEPENDS + libc.include.locale + .locale +) + +add_entrypoint_object( + freelocale + SRCS + freelocale.cpp + HDRS + freelocale.h + DEPENDS + libc.include.locale + .locale +) diff --git a/libc/src/locale/duplocale.cpp b/libc/src/locale/duplocale.cpp new file mode 100644 index 0000000000000..d1bd0835121fc --- /dev/null +++ b/libc/src/locale/duplocale.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of duplocale ---------------------------------------===// +// +// 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/locale/duplocale.h" +#include "include/llvm-libc-macros/locale-macros.h" +#include "src/locale/locale.h" + +#include "src/__support/CPP/string_view.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(locale_t, duplocale, (locale_t loc)) { return loc; } + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/locale/duplocale.h b/libc/src/locale/duplocale.h new file mode 100644 index 0000000000000..a745383860d83 --- /dev/null +++ b/libc/src/locale/duplocale.h @@ -0,0 +1,22 @@ +//===-- Implementation header for duplocale ---------------------*- 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_LOCALE_DUPLOCALE_H +#define LLVM_LIBC_SRC_LOCALE_DUPLOCALE_H + +#include "src/__support/macros/config.h" + +#include "hdr/types/locale_t.h" + +namespace LIBC_NAMESPACE_DECL { + +locale_t duplocale(locale_t loc); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_LOCALE_DUPLOCALE_H diff --git a/libc/src/locale/freelocale.cpp b/libc/src/locale/freelocale.cpp new file mode 100644 index 0000000000000..2008995f101bf --- /dev/null +++ b/libc/src/locale/freelocale.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of freelocale --------------------------------------===// +// +// 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/locale/freelocale.h" +#include "include/llvm-libc-macros/locale-macros.h" +#include "src/locale/locale.h" + +#include "src/__support/CPP/string_view.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(void, freelocale, (locale_t)) {} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/locale/freelocale.h b/libc/src/locale/freelocale.h new file mode 100644 index 0000000000000..77ece30430738 --- /dev/null +++ b/libc/src/locale/freelocale.h @@ -0,0 +1,22 @@ +//===-- Implementation header for freelocale --------------------*- 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_LOCALE_FREELOCALE_H +#define LLVM_LIBC_SRC_LOCALE_FREELOCALE_H + +#include "src/__support/macros/config.h" + +#include "hdr/types/locale_t.h" + +namespace LIBC_NAMESPACE_DECL { + +void freelocale(locale_t loc); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_LOCALE_FREELOCALE_H diff --git a/libc/src/locale/locale.cpp b/libc/src/locale/locale.cpp new file mode 100644 index 0000000000000..18ebc33ad5823 --- /dev/null +++ b/libc/src/locale/locale.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of locale ------------------------------------------===// +// +// 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/locale/locale.h" + +#include "include/llvm-libc-macros/locale-macros.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +__locale_t c_locale = {nullptr}; + +LIBC_THREAD_LOCAL locale_t locale = nullptr; + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/locale/locale.h b/libc/src/locale/locale.h new file mode 100644 index 0000000000000..6d6db2bcacad3 --- /dev/null +++ b/libc/src/locale/locale.h @@ -0,0 +1,36 @@ +//===-- Implementation header for the locale --------------------*- 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_LOCALE_LOCALECONV_H +#define LLVM_LIBC_SRC_LOCALE_LOCALECONV_H + +#include "src/__support/macros/attributes.h" +#include "src/__support/macros/config.h" + +#include "hdr/types/locale_t.h" + +#include + +namespace LIBC_NAMESPACE_DECL { + +// We only support the "C" locale right now. +static constexpr size_t MAX_LOCALE_NAME_SIZE = 2; + +struct __locale_data { + char name[MAX_LOCALE_NAME_SIZE]; +}; + +// The pointer to the default "C" locale. +extern __locale_t c_locale; + +// The global locale instance. +LIBC_THREAD_LOCAL extern locale_t locale; + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_LOCALE_LOCALECONV_H diff --git a/libc/src/locale/localeconv.cpp b/libc/src/locale/localeconv.cpp new file mode 100644 index 0000000000000..e4d7536bf1ffb --- /dev/null +++ b/libc/src/locale/localeconv.cpp @@ -0,0 +1,49 @@ +//===-- Implementation of localeconv --------------------------------------===// +// +// 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/locale/localeconv.h" + +#include "src/__support/CPP/limits.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +static char DOT_STRING[] = "."; +static char EMPTY_STRING[] = ""; + +static struct lconv C_LCONV = { + .decimal_point = DOT_STRING, + .thousands_sep = EMPTY_STRING, + .grouping = EMPTY_STRING, + .mon_decimal_point = EMPTY_STRING, + .mon_thousands_sep = EMPTY_STRING, + .mon_grouping = EMPTY_STRING, + .positive_sign = EMPTY_STRING, + .negative_sign = EMPTY_STRING, + .currency_symbol = EMPTY_STRING, + .frac_digits = CHAR_MAX, + .p_cs_precedes = CHAR_MAX, + .n_cs_precedes = CHAR_MAX, + .p_sep_by_space = CHAR_MAX, + .n_sep_by_space = CHAR_MAX, + .p_sign_posn = CHAR_MAX, + .n_sign_posn = CHAR_MAX, + .int_curr_symbol = EMPTY_STRING, + .int_frac_digits = CHAR_MAX, + .int_p_cs_precedes = CHAR_MAX, + .int_n_cs_precedes = CHAR_MAX, + .int_p_sep_by_space = CHAR_MAX, + .int_n_sep_by_space = CHAR_MAX, + .int_p_sign_posn = CHAR_MAX, + .int_n_sign_posn = CHAR_MAX, +}; + +LLVM_LIBC_FUNCTION(struct lconv *, localeconv, ()) { return &C_LCONV; } + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/locale/localeconv.h b/libc/src/locale/localeconv.h new file mode 100644 index 0000000000000..a8f7599b572bf --- /dev/null +++ b/libc/src/locale/localeconv.h @@ -0,0 +1,22 @@ +//===-- Implementation header for localeconv --------------------*- 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_LOCALE_LOCALECONV_H +#define LLVM_LIBC_SRC_LOCALE_LOCALECONV_H + +#include "src/__support/macros/config.h" + +#include "include/llvm-libc-types/struct_lconv.h" + +namespace LIBC_NAMESPACE_DECL { + +struct lconv *localeconv(); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_LOCALE_LOCALECONV_H diff --git a/libc/src/locale/newlocale.cpp b/libc/src/locale/newlocale.cpp new file mode 100644 index 0000000000000..379e7e6385d09 --- /dev/null +++ b/libc/src/locale/newlocale.cpp @@ -0,0 +1,28 @@ +//===-- Implementation of newlocale ---------------------------------------===// +// +// 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/locale/newlocale.h" +#include "include/llvm-libc-macros/locale-macros.h" +#include "src/locale/locale.h" + +#include "src/__support/CPP/string_view.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(locale_t, newlocale, + (int category_mask, const char *locale_name, locale_t)) { + cpp::string_view name(locale_name); + if (category_mask > LC_ALL || (!name.empty() && name != "C")) + return nullptr; + + return &c_locale; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/locale/newlocale.h b/libc/src/locale/newlocale.h new file mode 100644 index 0000000000000..08a0071cb7aea --- /dev/null +++ b/libc/src/locale/newlocale.h @@ -0,0 +1,22 @@ +//===-- Implementation header for setlocale ---------------------*- 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_LOCALE_SETLOCALE_H +#define LLVM_LIBC_SRC_LOCALE_SETLOCALE_H + +#include "src/__support/macros/config.h" + +#include "hdr/types/locale_t.h" + +namespace LIBC_NAMESPACE_DECL { + +locale_t newlocale(int category_mask, const char *locale_name, locale_t base); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_LOCALE_SETLOCALE_H diff --git a/libc/src/locale/setlocale.cpp b/libc/src/locale/setlocale.cpp new file mode 100644 index 0000000000000..0950ad73cbe2c --- /dev/null +++ b/libc/src/locale/setlocale.cpp @@ -0,0 +1,28 @@ +//===-- Implementation of setlocale ---------------------------------------===// +// +// 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/locale/setlocale.h" +#include "include/llvm-libc-macros/locale-macros.h" +#include "src/locale/locale.h" + +#include "src/__support/CPP/string_view.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(char *, setlocale, (int category, const char *locale_name)) { + cpp::string_view name(locale_name); + if (category > LC_ALL || (!name.empty() && name != "C")) + return nullptr; + + static char locale_str[] = "C"; + return locale_str; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/locale/setlocale.h b/libc/src/locale/setlocale.h new file mode 100644 index 0000000000000..a9213cf409a7b --- /dev/null +++ b/libc/src/locale/setlocale.h @@ -0,0 +1,22 @@ +//===-- Implementation header for setlocale ---------------------*- 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_LOCALE_SETLOCALE_H +#define LLVM_LIBC_SRC_LOCALE_SETLOCALE_H + +#include "src/__support/macros/config.h" + +#include "hdr/types/locale_t.h" + +namespace LIBC_NAMESPACE_DECL { + +char *setlocale(int category, const char *locale_name); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_LOCALE_SETLOCALE_H diff --git a/libc/src/locale/uselocale.cpp b/libc/src/locale/uselocale.cpp new file mode 100644 index 0000000000000..d6fdad248f12b --- /dev/null +++ b/libc/src/locale/uselocale.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of uselocale ---------------------------------------===// +// +// 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/locale/uselocale.h" +#include "src/locale/locale.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(locale_t, uselocale, (locale_t newloc)) { + if (!newloc) + return locale; + return locale = newloc; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/locale/uselocale.h b/libc/src/locale/uselocale.h new file mode 100644 index 0000000000000..15403490d2f8c --- /dev/null +++ b/libc/src/locale/uselocale.h @@ -0,0 +1,22 @@ +//===-- Implementation header for uselocale ---------------------*- 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_LOCALE_USELOCALE_H +#define LLVM_LIBC_SRC_LOCALE_USELOCALE_H + +#include "src/__support/macros/config.h" + +#include "hdr/types/locale_t.h" + +namespace LIBC_NAMESPACE_DECL { + +locale_t uselocale(locale_t newloc); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_LOCALE_USELOCALE_H diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt index 60ea7e6a90d71..ddc6a5c7f6965 100644 --- a/libc/test/src/CMakeLists.txt +++ b/libc/test/src/CMakeLists.txt @@ -82,6 +82,7 @@ add_subdirectory(setjmp) add_subdirectory(signal) add_subdirectory(spawn) add_subdirectory(time) +add_subdirectory(locale) if(${LIBC_TARGET_OS} STREQUAL "linux") add_subdirectory(pthread) diff --git a/libc/test/src/locale/CMakeLists.txt b/libc/test/src/locale/CMakeLists.txt new file mode 100644 index 0000000000000..3192004db26dd --- /dev/null +++ b/libc/test/src/locale/CMakeLists.txt @@ -0,0 +1,25 @@ +add_custom_target(libc-locale-tests) + +add_libc_test( + locale_test + SUITE + libc-locale-tests + SRCS + locale_test.cpp + DEPENDS + libc.include.locale + libc.src.locale.newlocale + libc.src.locale.uselocale + libc.src.locale.freelocale +) + +add_libc_test( + localeconv_test + SUITE + libc-locale-tests + SRCS + localeconv_test.cpp + DEPENDS + libc.include.locale + libc.src.locale.localeconv +) diff --git a/libc/test/src/locale/locale_test.cpp b/libc/test/src/locale/locale_test.cpp new file mode 100644 index 0000000000000..bc48bb851f4e4 --- /dev/null +++ b/libc/test/src/locale/locale_test.cpp @@ -0,0 +1,27 @@ +//===-- Unittests for locale ----------------------------------------------===// +// +// 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/locale/freelocale.h" +#include "src/locale/newlocale.h" +#include "src/locale/uselocale.h" + +#include "test/UnitTest/Test.h" + +#include "include/llvm-libc-macros/locale-macros.h" + +TEST(LlvmLibcLocale, DefaultLocale) { + locale_t new_locale = LIBC_NAMESPACE::newlocale(LC_ALL, "C", nullptr); + EXPECT_NE(new_locale, static_cast(nullptr)); + + locale_t old_locale = LIBC_NAMESPACE::uselocale(new_locale); + EXPECT_NE(old_locale, static_cast(nullptr)); + + LIBC_NAMESPACE::freelocale(new_locale); + + LIBC_NAMESPACE::uselocale(old_locale); +} diff --git a/libc/test/src/locale/localeconv_test.cpp b/libc/test/src/locale/localeconv_test.cpp new file mode 100644 index 0000000000000..79264276dec35 --- /dev/null +++ b/libc/test/src/locale/localeconv_test.cpp @@ -0,0 +1,17 @@ +//===-- Unittests for localeconv ------------------------------------------===// +// +// 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 "include/llvm-libc-macros/locale-macros.h" +#include "src/locale/localeconv.h" + +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcLocale, DefaultLocale) { + struct lconv *conv = LIBC_NAMESPACE::localeconv(); + EXPECT_STREQ(conv->decimal_point, "."); +} From de606a377bf37efd372f04509c824a32910bacdb Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Fri, 9 Aug 2024 21:27:28 -0500 Subject: [PATCH 2/2] [libc] Add `ctype.h` locale variants Summary: This patch adds all the libc ctype variants. These ignore the locale ingormation completely, so they're pretty much just stubs. Because these use locale information, which is system scope, we do not enable building them outisde of full build mode. --- libc/config/gpu/entrypoints.txt | 14 ++ libc/config/linux/x86_64/entrypoints.txt | 16 +++ libc/include/CMakeLists.txt | 1 + libc/newhdrgen/yaml/ctype.yaml | 102 ++++++++++++++- libc/spec/stdc.td | 74 ++++++++++- libc/src/ctype/CMakeLists.txt | 156 +++++++++++++++++++++++ libc/src/ctype/isalnum.cpp | 2 - libc/src/ctype/isalnum_l.cpp | 21 +++ libc/src/ctype/isalnum_l.h | 21 +++ libc/src/ctype/isalpha.cpp | 2 - libc/src/ctype/isalpha_l.cpp | 21 +++ libc/src/ctype/isalpha_l.h | 21 +++ libc/src/ctype/isblank.cpp | 2 - libc/src/ctype/isblank_l.cpp | 20 +++ libc/src/ctype/isblank_l.h | 21 +++ libc/src/ctype/iscntrl.cpp | 2 - libc/src/ctype/iscntrl_l.cpp | 21 +++ libc/src/ctype/iscntrl_l.h | 21 +++ libc/src/ctype/isdigit.cpp | 2 - libc/src/ctype/isdigit_l.cpp | 20 +++ libc/src/ctype/isdigit_l.h | 21 +++ libc/src/ctype/isgraph.cpp | 2 - libc/src/ctype/isgraph_l.cpp | 21 +++ libc/src/ctype/isgraph_l.h | 21 +++ libc/src/ctype/islower.cpp | 2 - libc/src/ctype/islower_l.cpp | 21 +++ libc/src/ctype/islower_l.h | 21 +++ libc/src/ctype/isprint.cpp | 2 - libc/src/ctype/isprint_l.cpp | 21 +++ libc/src/ctype/isprint_l.h | 21 +++ libc/src/ctype/ispunct.cpp | 2 - libc/src/ctype/ispunct_l.cpp | 22 ++++ libc/src/ctype/ispunct_l.h | 21 +++ libc/src/ctype/isspace.cpp | 2 - libc/src/ctype/isspace_l.cpp | 21 +++ libc/src/ctype/isspace_l.h | 21 +++ libc/src/ctype/isupper.cpp | 2 - libc/src/ctype/isupper_l.cpp | 21 +++ libc/src/ctype/isupper_l.h | 21 +++ libc/src/ctype/isxdigit.cpp | 2 - libc/src/ctype/isxdigit_l.cpp | 22 ++++ libc/src/ctype/isxdigit_l.h | 21 +++ libc/src/ctype/tolower.cpp | 2 - libc/src/ctype/tolower_l.cpp | 21 +++ libc/src/ctype/tolower_l.h | 21 +++ libc/src/ctype/toupper.cpp | 2 - libc/src/ctype/toupper_l.cpp | 23 ++++ libc/src/ctype/toupper_l.h | 21 +++ 48 files changed, 950 insertions(+), 31 deletions(-) create mode 100644 libc/src/ctype/isalnum_l.cpp create mode 100644 libc/src/ctype/isalnum_l.h create mode 100644 libc/src/ctype/isalpha_l.cpp create mode 100644 libc/src/ctype/isalpha_l.h create mode 100644 libc/src/ctype/isblank_l.cpp create mode 100644 libc/src/ctype/isblank_l.h create mode 100644 libc/src/ctype/iscntrl_l.cpp create mode 100644 libc/src/ctype/iscntrl_l.h create mode 100644 libc/src/ctype/isdigit_l.cpp create mode 100644 libc/src/ctype/isdigit_l.h create mode 100644 libc/src/ctype/isgraph_l.cpp create mode 100644 libc/src/ctype/isgraph_l.h create mode 100644 libc/src/ctype/islower_l.cpp create mode 100644 libc/src/ctype/islower_l.h create mode 100644 libc/src/ctype/isprint_l.cpp create mode 100644 libc/src/ctype/isprint_l.h create mode 100644 libc/src/ctype/ispunct_l.cpp create mode 100644 libc/src/ctype/ispunct_l.h create mode 100644 libc/src/ctype/isspace_l.cpp create mode 100644 libc/src/ctype/isspace_l.h create mode 100644 libc/src/ctype/isupper_l.cpp create mode 100644 libc/src/ctype/isupper_l.h create mode 100644 libc/src/ctype/isxdigit_l.cpp create mode 100644 libc/src/ctype/isxdigit_l.h create mode 100644 libc/src/ctype/tolower_l.cpp create mode 100644 libc/src/ctype/tolower_l.h create mode 100644 libc/src/ctype/toupper_l.cpp create mode 100644 libc/src/ctype/toupper_l.h diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt index 592c8cdb7ae77..9a4e7f3443beb 100644 --- a/libc/config/gpu/entrypoints.txt +++ b/libc/config/gpu/entrypoints.txt @@ -4,21 +4,35 @@ set(TARGET_LIBC_ENTRYPOINTS # ctype.h entrypoints libc.src.ctype.isalnum + libc.src.ctype.isalnum_l libc.src.ctype.isalpha + libc.src.ctype.isalpha_l libc.src.ctype.isascii libc.src.ctype.isblank + libc.src.ctype.isblank_l libc.src.ctype.iscntrl + libc.src.ctype.iscntrl_l libc.src.ctype.isdigit + libc.src.ctype.isdigit_l libc.src.ctype.isgraph + libc.src.ctype.isgraph_l libc.src.ctype.islower + libc.src.ctype.islower_l libc.src.ctype.isprint + libc.src.ctype.isprint_l libc.src.ctype.ispunct + libc.src.ctype.ispunct_l libc.src.ctype.isspace + libc.src.ctype.isspace_l libc.src.ctype.isupper + libc.src.ctype.isupper_l libc.src.ctype.isxdigit + libc.src.ctype.isxdigit_l libc.src.ctype.toascii libc.src.ctype.tolower + libc.src.ctype.tolower_l libc.src.ctype.toupper + libc.src.ctype.toupper_l # string.h entrypoints libc.src.string.bcmp diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index e7c3c7db64abe..bac1e3cfa85da 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -782,6 +782,22 @@ endif() if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS + # ctype.h entrypoints + libc.src.ctype.isalnum_l + libc.src.ctype.isalpha_l + libc.src.ctype.isblank_l + libc.src.ctype.iscntrl_l + libc.src.ctype.isdigit_l + libc.src.ctype.isgraph_l + libc.src.ctype.islower_l + libc.src.ctype.isprint_l + libc.src.ctype.ispunct_l + libc.src.ctype.isspace_l + libc.src.ctype.isupper_l + libc.src.ctype.isxdigit_l + libc.src.ctype.tolower_l + libc.src.ctype.toupper_l + # assert.h entrypoints libc.src.assert.__assert_fail diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index 733582c182735..8c0b2a2b1c574 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -45,6 +45,7 @@ add_header_macro( ctype.h DEPENDS .llvm_libc_common_h + .llvm-libc-types.locale_t ) add_header_macro( diff --git a/libc/newhdrgen/yaml/ctype.yaml b/libc/newhdrgen/yaml/ctype.yaml index f3108a34d4337..b4823c3e53234 100644 --- a/libc/newhdrgen/yaml/ctype.yaml +++ b/libc/newhdrgen/yaml/ctype.yaml @@ -1,6 +1,7 @@ header: ctype.h macros: [] -types: [] +types: + - type_name: locale_t enums: [] objects: [] functions: @@ -100,4 +101,101 @@ functions: return_type: int arguments: - type: int - functions: null + - name: isalnum_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: isalpha_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: isblank_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: iscntrl_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: isdigit_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: isgraph_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: islower_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: isprint_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: ispunct_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: isspace_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: isupper_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: isxdigit_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: tolower_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t + - name: toupper_l + standards: + - stdc + return_type: int + arguments: + - type: int + - type: locale_t diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 76a9ed123356a..6fd3e6d861848 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -35,7 +35,9 @@ def StdC : StandardSpec<"stdc"> { HeaderSpec CType = HeaderSpec< "ctype.h", [], // Macros - [], // Types + [ + LocaleT + ], // Types [], // Enumerations [ FunctionSpec< @@ -108,6 +110,76 @@ def StdC : StandardSpec<"stdc"> { RetValSpec, [ArgSpec] >, + FunctionSpec< + "isalnum_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "isalpha_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "isblank_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "iscntrl_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "isdigit_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "isgraph_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "islower_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "isprint_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "ispunct_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "isspace_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "isupper_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "isxdigit_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "tolower_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "toupper_l", + RetValSpec, + [ArgSpec, ArgSpec] + >, ] >; diff --git a/libc/src/ctype/CMakeLists.txt b/libc/src/ctype/CMakeLists.txt index ae4eec9615dc1..8830c1bccf9ea 100644 --- a/libc/src/ctype/CMakeLists.txt +++ b/libc/src/ctype/CMakeLists.txt @@ -146,3 +146,159 @@ add_entrypoint_object( DEPENDS libc.src.__support.ctype_utils ) + +# Do not build the locale versions in overlay mode. +if(NOT LLVM_LIBC_FULL_BUILD) + return() +endif() + +add_entrypoint_object( + isalnum_l + SRCS + isalnum_l.cpp + HDRS + isalnum_l.h + DEPENDS + libc.include.ctype + libc.src.__support.ctype_utils + libc.hdr.types.locale_t +) + +add_entrypoint_object( + isalpha_l + SRCS + isalpha_l.cpp + HDRS + isalpha_l.h + DEPENDS + libc.src.__support.ctype_utils + libc.hdr.types.locale_t +) + +add_entrypoint_object( + isblank_l + SRCS + isblank_l.cpp + HDRS + isblank_l.h + DEPENDS + libc.hdr.types.locale_t +) + +add_entrypoint_object( + iscntrl_l + SRCS + iscntrl_l.cpp + HDRS + iscntrl_l.h + DEPENDS + libc.hdr.types.locale_t +) + +add_entrypoint_object( + isdigit_l + SRCS + isdigit_l.cpp + HDRS + isdigit_l.h + DEPENDS + libc.src.__support.ctype_utils + libc.hdr.types.locale_t +) + +add_entrypoint_object( + isgraph_l + SRCS + isgraph_l.cpp + HDRS + isgraph_l.h + DEPENDS + libc.src.__support.ctype_utils + libc.hdr.types.locale_t +) + +add_entrypoint_object( + islower_l + SRCS + islower_l.cpp + HDRS + islower_l.h + DEPENDS + libc.src.__support.ctype_utils + libc.hdr.types.locale_t +) + +add_entrypoint_object( + isprint_l + SRCS + isprint_l.cpp + HDRS + isprint_l.h + DEPENDS + libc.hdr.types.locale_t +) + +add_entrypoint_object( + ispunct_l + SRCS + ispunct_l.cpp + HDRS + ispunct_l.h + DEPENDS + libc.src.__support.ctype_utils + libc.hdr.types.locale_t +) + +add_entrypoint_object( + isspace_l + SRCS + isspace_l.cpp + HDRS + isspace_l.h + DEPENDS + libc.hdr.types.locale_t +) + +add_entrypoint_object( + isupper_l + SRCS + isupper_l.cpp + HDRS + isupper_l.h + DEPENDS + libc.src.__support.ctype_utils + libc.hdr.types.locale_t +) + +add_entrypoint_object( + isxdigit_l + SRCS + isxdigit_l.cpp + HDRS + isxdigit_l.h + DEPENDS + libc.src.__support.ctype_utils + libc.hdr.types.locale_t +) + +add_entrypoint_object( + tolower_l + SRCS + tolower_l.cpp + HDRS + tolower_l.h + DEPENDS + libc.src.__support.ctype_utils + libc.hdr.types.locale_t +) + +add_entrypoint_object( + toupper_l + SRCS + toupper_l.cpp + HDRS + toupper_l.h + DEPENDS + libc.src.__support.ctype_utils + libc.hdr.types.locale_t +) diff --git a/libc/src/ctype/isalnum.cpp b/libc/src/ctype/isalnum.cpp index 382553c23a6bf..54a3e35748879 100644 --- a/libc/src/ctype/isalnum.cpp +++ b/libc/src/ctype/isalnum.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, isalnum, (int c)) { return static_cast(internal::isalnum(static_cast(c))); } diff --git a/libc/src/ctype/isalnum_l.cpp b/libc/src/ctype/isalnum_l.cpp new file mode 100644 index 0000000000000..671d9b75c4c33 --- /dev/null +++ b/libc/src/ctype/isalnum_l.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of isalnum -----------------------------------------===// +// +// 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/ctype/isalnum_l.h" +#include "src/__support/ctype_utils.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, isalnum_l, (int c, locale_t)) { + return static_cast(internal::isalnum(static_cast(c))); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isalnum_l.h b/libc/src/ctype/isalnum_l.h new file mode 100644 index 0000000000000..5bc892e6c8747 --- /dev/null +++ b/libc/src/ctype/isalnum_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for isalnum_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_CTYPE_ISALNUM_H +#define LLVM_LIBC_SRC_CTYPE_ISALNUM_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int isalnum_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISALNUM_H diff --git a/libc/src/ctype/isalpha.cpp b/libc/src/ctype/isalpha.cpp index 1a63406780b6e..78b26f6a486ea 100644 --- a/libc/src/ctype/isalpha.cpp +++ b/libc/src/ctype/isalpha.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, isalpha, (int c)) { return static_cast(internal::isalpha(static_cast(c))); } diff --git a/libc/src/ctype/isalpha_l.cpp b/libc/src/ctype/isalpha_l.cpp new file mode 100644 index 0000000000000..0619d979bedf2 --- /dev/null +++ b/libc/src/ctype/isalpha_l.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of isalpha -----------------------------------------===// +// +// 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/ctype/isalpha_l.h" + +#include "src/__support/common.h" +#include "src/__support/ctype_utils.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, isalpha_l, (int c, locale_t)) { + return static_cast(internal::isalpha(static_cast(c))); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isalpha_l.h b/libc/src/ctype/isalpha_l.h new file mode 100644 index 0000000000000..3591f1175cb9a --- /dev/null +++ b/libc/src/ctype/isalpha_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for isalpha_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_CTYPE_ISALPHA_H +#define LLVM_LIBC_SRC_CTYPE_ISALPHA_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int isalpha_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISALPHA_H diff --git a/libc/src/ctype/isblank.cpp b/libc/src/ctype/isblank.cpp index a4f33d265bd2d..e0a20829f86ce 100644 --- a/libc/src/ctype/isblank.cpp +++ b/libc/src/ctype/isblank.cpp @@ -13,8 +13,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, isblank, (int c)) { return static_cast(c == ' ' || c == '\t'); } diff --git a/libc/src/ctype/isblank_l.cpp b/libc/src/ctype/isblank_l.cpp new file mode 100644 index 0000000000000..4f6b0bfac2972 --- /dev/null +++ b/libc/src/ctype/isblank_l.cpp @@ -0,0 +1,20 @@ +//===-- Implementation of isblank -----------------------------------------===// +// +// 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/ctype/isblank_l.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, isblank_l, (int c, locale_t)) { + return static_cast(c == ' ' || c == '\t'); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isblank_l.h b/libc/src/ctype/isblank_l.h new file mode 100644 index 0000000000000..61ede30ae7677 --- /dev/null +++ b/libc/src/ctype/isblank_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for isblank_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_CTYPE_ISBLANK_H +#define LLVM_LIBC_SRC_CTYPE_ISBLANK_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int isblank_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISBLANK_H diff --git a/libc/src/ctype/iscntrl.cpp b/libc/src/ctype/iscntrl.cpp index fb582fd6ef082..2218adfcc33f3 100644 --- a/libc/src/ctype/iscntrl.cpp +++ b/libc/src/ctype/iscntrl.cpp @@ -13,8 +13,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, iscntrl, (int c)) { const unsigned ch = static_cast(c); return static_cast(ch < 0x20 || ch == 0x7f); diff --git a/libc/src/ctype/iscntrl_l.cpp b/libc/src/ctype/iscntrl_l.cpp new file mode 100644 index 0000000000000..83aa480299fad --- /dev/null +++ b/libc/src/ctype/iscntrl_l.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of iscntrl -----------------------------------------===// +// +// 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/ctype/iscntrl_l.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, iscntrl_l, (int c, locale_t)) { + const unsigned ch = static_cast(c); + return static_cast(ch < 0x20 || ch == 0x7f); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/iscntrl_l.h b/libc/src/ctype/iscntrl_l.h new file mode 100644 index 0000000000000..7dee44fcd0beb --- /dev/null +++ b/libc/src/ctype/iscntrl_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for iscntrl_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_CTYPE_ISCNTRL_H +#define LLVM_LIBC_SRC_CTYPE_ISCNTRL_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int iscntrl_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISCNTRL_H diff --git a/libc/src/ctype/isdigit.cpp b/libc/src/ctype/isdigit.cpp index 43c5f1940c7f0..1f711943861f8 100644 --- a/libc/src/ctype/isdigit.cpp +++ b/libc/src/ctype/isdigit.cpp @@ -13,8 +13,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, isdigit, (int c)) { return static_cast(internal::isdigit(static_cast(c))); } diff --git a/libc/src/ctype/isdigit_l.cpp b/libc/src/ctype/isdigit_l.cpp new file mode 100644 index 0000000000000..ca981362bfe83 --- /dev/null +++ b/libc/src/ctype/isdigit_l.cpp @@ -0,0 +1,20 @@ +//===-- Implementation of isdigit -----------------------------------------===// +// +// 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/ctype/isdigit_l.h" +#include "src/__support/common.h" +#include "src/__support/ctype_utils.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, isdigit_l, (int c, locale_t)) { + return static_cast(internal::isdigit(static_cast(c))); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isdigit_l.h b/libc/src/ctype/isdigit_l.h new file mode 100644 index 0000000000000..abeec3464941a --- /dev/null +++ b/libc/src/ctype/isdigit_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for isdigit_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_CTYPE_ISDIGIT_H +#define LLVM_LIBC_SRC_CTYPE_ISDIGIT_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int isdigit_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISDIGIT_H diff --git a/libc/src/ctype/isgraph.cpp b/libc/src/ctype/isgraph.cpp index a5b6e501b5813..74bb2e75d138e 100644 --- a/libc/src/ctype/isgraph.cpp +++ b/libc/src/ctype/isgraph.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, isgraph, (int c)) { return static_cast(internal::isgraph(static_cast(c))); } diff --git a/libc/src/ctype/isgraph_l.cpp b/libc/src/ctype/isgraph_l.cpp new file mode 100644 index 0000000000000..cbef6df148aed --- /dev/null +++ b/libc/src/ctype/isgraph_l.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of isgraph -----------------------------------------===// +// +// 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/ctype/isgraph_l.h" + +#include "src/__support/common.h" +#include "src/__support/ctype_utils.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, isgraph_l, (int c, locale_t)) { + return static_cast(internal::isgraph(static_cast(c))); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isgraph_l.h b/libc/src/ctype/isgraph_l.h new file mode 100644 index 0000000000000..d96a460865509 --- /dev/null +++ b/libc/src/ctype/isgraph_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for isgraph_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_CTYPE_ISGRAPH_H +#define LLVM_LIBC_SRC_CTYPE_ISGRAPH_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int isgraph_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISGRAPH_H diff --git a/libc/src/ctype/islower.cpp b/libc/src/ctype/islower.cpp index 61ccbcc1db413..831aad32d3a22 100644 --- a/libc/src/ctype/islower.cpp +++ b/libc/src/ctype/islower.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, islower, (int c)) { return static_cast(internal::islower(static_cast(c))); } diff --git a/libc/src/ctype/islower_l.cpp b/libc/src/ctype/islower_l.cpp new file mode 100644 index 0000000000000..b9be6acc81c99 --- /dev/null +++ b/libc/src/ctype/islower_l.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of islower -----------------------------------------===// +// +// 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/ctype/islower_l.h" +#include "src/__support/ctype_utils.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, islower_l, (int c, locale_t)) { + return static_cast(internal::islower(static_cast(c))); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/islower_l.h b/libc/src/ctype/islower_l.h new file mode 100644 index 0000000000000..7d3e2f139602b --- /dev/null +++ b/libc/src/ctype/islower_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for islower_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_CTYPE_ISLOWER_H +#define LLVM_LIBC_SRC_CTYPE_ISLOWER_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int islower_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISLOWER_H diff --git a/libc/src/ctype/isprint.cpp b/libc/src/ctype/isprint.cpp index 42ab9cc8d238a..349aefe1c17bb 100644 --- a/libc/src/ctype/isprint.cpp +++ b/libc/src/ctype/isprint.cpp @@ -13,8 +13,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, isprint, (int c)) { const unsigned ch = static_cast(c); return static_cast((ch - ' ') < 95); diff --git a/libc/src/ctype/isprint_l.cpp b/libc/src/ctype/isprint_l.cpp new file mode 100644 index 0000000000000..8f51f7f0e3e94 --- /dev/null +++ b/libc/src/ctype/isprint_l.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of isprint -----------------------------------------===// +// +// 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/ctype/isprint_l.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, isprint_l, (int c, locale_t)) { + const unsigned ch = static_cast(c); + return static_cast((ch - ' ') < 95); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isprint_l.h b/libc/src/ctype/isprint_l.h new file mode 100644 index 0000000000000..bd2ea9354c36a --- /dev/null +++ b/libc/src/ctype/isprint_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for isprint_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_CTYPE_ISPRINT_H +#define LLVM_LIBC_SRC_CTYPE_ISPRINT_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int isprint_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISPRINT_H diff --git a/libc/src/ctype/ispunct.cpp b/libc/src/ctype/ispunct.cpp index c1906e3acdd80..0635294220b9c 100644 --- a/libc/src/ctype/ispunct.cpp +++ b/libc/src/ctype/ispunct.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, ispunct, (int c)) { const unsigned ch = static_cast(c); return static_cast(!internal::isalnum(ch) && internal::isgraph(ch)); diff --git a/libc/src/ctype/ispunct_l.cpp b/libc/src/ctype/ispunct_l.cpp new file mode 100644 index 0000000000000..e825fbe2001b0 --- /dev/null +++ b/libc/src/ctype/ispunct_l.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of ispunct -----------------------------------------===// +// +// 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/ctype/ispunct_l.h" + +#include "src/__support/common.h" +#include "src/__support/ctype_utils.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, ispunct_l, (int c, locale_t)) { + const unsigned ch = static_cast(c); + return static_cast(!internal::isalnum(ch) && internal::isgraph(ch)); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/ispunct_l.h b/libc/src/ctype/ispunct_l.h new file mode 100644 index 0000000000000..862daf4836f78 --- /dev/null +++ b/libc/src/ctype/ispunct_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for ispunct_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_CTYPE_ISPUNCT_H +#define LLVM_LIBC_SRC_CTYPE_ISPUNCT_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int ispunct_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISPUNCT_H diff --git a/libc/src/ctype/isspace.cpp b/libc/src/ctype/isspace.cpp index f890849378784..005bf460fc103 100644 --- a/libc/src/ctype/isspace.cpp +++ b/libc/src/ctype/isspace.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, isspace, (int c)) { return static_cast(internal::isspace(static_cast(c))); } diff --git a/libc/src/ctype/isspace_l.cpp b/libc/src/ctype/isspace_l.cpp new file mode 100644 index 0000000000000..5c46dd6805126 --- /dev/null +++ b/libc/src/ctype/isspace_l.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of isspace -----------------------------------------===// +// +// 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/ctype/isspace_l.h" +#include "src/__support/ctype_utils.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, isspace_l, (int c, locale_t)) { + return static_cast(internal::isspace(static_cast(c))); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isspace_l.h b/libc/src/ctype/isspace_l.h new file mode 100644 index 0000000000000..61bbf127956da --- /dev/null +++ b/libc/src/ctype/isspace_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for isspace_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_CTYPE_ISSPACE_H +#define LLVM_LIBC_SRC_CTYPE_ISSPACE_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int isspace_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISSPACE_H diff --git a/libc/src/ctype/isupper.cpp b/libc/src/ctype/isupper.cpp index 8f929ea1a009e..965fa336b28b4 100644 --- a/libc/src/ctype/isupper.cpp +++ b/libc/src/ctype/isupper.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, isupper, (int c)) { return static_cast(internal::isupper(static_cast(c))); } diff --git a/libc/src/ctype/isupper_l.cpp b/libc/src/ctype/isupper_l.cpp new file mode 100644 index 0000000000000..358990261d603 --- /dev/null +++ b/libc/src/ctype/isupper_l.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of isupper -----------------------------------------===// +// +// 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/ctype/isupper_l.h" +#include "src/__support/ctype_utils.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, isupper_l, (int c, locale_t)) { + return static_cast(internal::isupper(static_cast(c))); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isupper_l.h b/libc/src/ctype/isupper_l.h new file mode 100644 index 0000000000000..9bee7ef8c09f5 --- /dev/null +++ b/libc/src/ctype/isupper_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for isupper_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_CTYPE_ISUPPER_H +#define LLVM_LIBC_SRC_CTYPE_ISUPPER_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int isupper_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISUPPER_H diff --git a/libc/src/ctype/isxdigit.cpp b/libc/src/ctype/isxdigit.cpp index 391c5c53cee1e..6b730c354db08 100644 --- a/libc/src/ctype/isxdigit.cpp +++ b/libc/src/ctype/isxdigit.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, isxdigit, (int c)) { const unsigned ch = static_cast(c); return static_cast(internal::isdigit(ch) || (ch | 32) - 'a' < 6); diff --git a/libc/src/ctype/isxdigit_l.cpp b/libc/src/ctype/isxdigit_l.cpp new file mode 100644 index 0000000000000..8a5c7d4d28ab1 --- /dev/null +++ b/libc/src/ctype/isxdigit_l.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of isxdigit ----------------------------------------===// +// +// 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/ctype/isxdigit_l.h" +#include "src/__support/ctype_utils.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, isxdigit_l, (int c, locale_t)) { + const unsigned ch = static_cast(c); + return static_cast(internal::isdigit(ch) || (ch | 32) - 'a' < 6); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isxdigit_l.h b/libc/src/ctype/isxdigit_l.h new file mode 100644 index 0000000000000..ee847eda4eae9 --- /dev/null +++ b/libc/src/ctype/isxdigit_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for isxdigit_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_CTYPE_ISXDIGIT_H +#define LLVM_LIBC_SRC_CTYPE_ISXDIGIT_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int isxdigit_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_ISXDIGIT_H diff --git a/libc/src/ctype/tolower.cpp b/libc/src/ctype/tolower.cpp index e230428eef2b1..3ecad7bc5d5d5 100644 --- a/libc/src/ctype/tolower.cpp +++ b/libc/src/ctype/tolower.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, tolower, (int c)) { return internal::tolower(c); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/tolower_l.cpp b/libc/src/ctype/tolower_l.cpp new file mode 100644 index 0000000000000..7ccf31617e592 --- /dev/null +++ b/libc/src/ctype/tolower_l.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of tolower -----------------------------------------===// +// +// 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/ctype/tolower_l.h" +#include "src/__support/ctype_utils.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, tolower_l, (int c, locale_t)) { + return internal::tolower(c); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/tolower_l.h b/libc/src/ctype/tolower_l.h new file mode 100644 index 0000000000000..6099b8c813469 --- /dev/null +++ b/libc/src/ctype/tolower_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for tolower_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_CTYPE_TOLOWER_H +#define LLVM_LIBC_SRC_CTYPE_TOLOWER_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int tolower_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_TOLOWER_H diff --git a/libc/src/ctype/toupper.cpp b/libc/src/ctype/toupper.cpp index 97c1ac2c02b8c..b5a23fc7f588b 100644 --- a/libc/src/ctype/toupper.cpp +++ b/libc/src/ctype/toupper.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -// TODO: Currently restricted to default locale. -// These should be extended using locale information. LLVM_LIBC_FUNCTION(int, toupper, (int c)) { if (internal::islower(c)) return c - ('a' - 'A'); diff --git a/libc/src/ctype/toupper_l.cpp b/libc/src/ctype/toupper_l.cpp new file mode 100644 index 0000000000000..f536ff3623616 --- /dev/null +++ b/libc/src/ctype/toupper_l.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of toupper_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/ctype/toupper_l.h" +#include "src/__support/ctype_utils.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, toupper_l, (int c, locale_t)) { + if (internal::islower(c)) + return c - ('a' - 'A'); + return c; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/toupper_l.h b/libc/src/ctype/toupper_l.h new file mode 100644 index 0000000000000..8877c35d492bd --- /dev/null +++ b/libc/src/ctype/toupper_l.h @@ -0,0 +1,21 @@ +//===-- Implementation header for toupper_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_CTYPE_TOUPPER_H +#define LLVM_LIBC_SRC_CTYPE_TOUPPER_H + +#include "hdr/types/locale_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int toupper_l(int c, locale_t locale); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_CTYPE_TOUPPER_H