[libc-commits] [libc] [libc] Add `locale.h` and related stubs (PR #97494)
Izaak Schroeder via libc-commits
libc-commits at lists.llvm.org
Tue Jul 2 17:32:09 PDT 2024
https://github.com/izaakschroeder updated https://github.com/llvm/llvm-project/pull/97494
>From 8f5fdeed0cc2768a675a124ab4626bb628597ac3 Mon Sep 17 00:00:00 2001
From: Izaak Schroeder <izaak.schroeder at gmail.com>
Date: Tue, 2 Jul 2024 11:21:32 -0700
Subject: [PATCH] [libc] Add `locale.h` and related stubs
---
libc/config/linux/aarch64/entrypoints.txt | 27 +++++++
libc/config/linux/aarch64/headers.txt | 2 +
libc/config/linux/api.td | 7 ++
libc/config/linux/x86_64/entrypoints.txt | 27 +++++++
libc/config/linux/x86_64/headers.txt | 2 +
libc/include/CMakeLists.txt | 13 ++++
libc/include/ctype.h.def | 1 +
libc/include/llvm-libc-macros/CMakeLists.txt | 6 ++
libc/include/llvm-libc-macros/locale-macros.h | 30 ++++++++
libc/include/llvm-libc-macros/stdlib-macros.h | 4 +
libc/include/llvm-libc-types/CMakeLists.txt | 2 +
libc/include/llvm-libc-types/locale_t.h | 18 +++++
libc/include/llvm-libc-types/struct_lconv.h | 39 ++++++++++
libc/include/locale.h.def | 18 +++++
libc/include/stdlib.h.def | 1 +
libc/include/time.h.def | 2 +
libc/spec/posix.td | 57 +++++++++++++++
libc/spec/stdc.td | 57 ++++++++++++++-
libc/src/CMakeLists.txt | 1 +
libc/src/ctype/CMakeLists.txt | 73 +++++++++++++++++++
libc/src/ctype/isdigit_l.cpp | 17 +++++
libc/src/ctype/isdigit_l.h | 20 +++++
libc/src/ctype/islower_l.cpp | 20 +++++
libc/src/ctype/islower_l.h | 20 +++++
libc/src/ctype/isupper_l.cpp | 20 +++++
libc/src/ctype/isupper_l.h | 20 +++++
libc/src/ctype/isxdigit_l.cpp | 21 ++++++
libc/src/ctype/isxdigit_l.h | 20 +++++
libc/src/ctype/tolower_l.cpp | 20 +++++
libc/src/ctype/tolower_l.h | 20 +++++
libc/src/ctype/toupper_l.cpp | 21 ++++++
libc/src/ctype/toupper_l.h | 20 +++++
libc/src/locale/CMakeLists.txt | 60 +++++++++++++++
libc/src/locale/duplocale.cpp | 16 ++++
libc/src/locale/duplocale.h | 20 +++++
libc/src/locale/freelocale.cpp | 18 +++++
libc/src/locale/freelocale.h | 20 +++++
libc/src/locale/localeconv.cpp | 46 ++++++++++++
libc/src/locale/localeconv.h | 20 +++++
libc/src/locale/newlocale.cpp | 18 +++++
libc/src/locale/newlocale.h | 20 +++++
libc/src/locale/setlocale.cpp | 18 +++++
libc/src/locale/setlocale.h | 18 +++++
libc/src/locale/uselocale.cpp | 16 ++++
libc/src/locale/uselocale.h | 20 +++++
libc/src/stdlib/CMakeLists.txt | 60 +++++++++++++++
libc/src/stdlib/strtod_l.cpp | 22 ++++++
libc/src/stdlib/strtod_l.h | 22 ++++++
libc/src/stdlib/strtof_l.cpp | 22 ++++++
libc/src/stdlib/strtof_l.h | 22 ++++++
libc/src/stdlib/strtold_l.cpp | 22 ++++++
libc/src/stdlib/strtold_l.h | 21 ++++++
libc/src/stdlib/strtoll_l.cpp | 22 ++++++
libc/src/stdlib/strtoll_l.h | 21 ++++++
libc/src/stdlib/strtoull_l.cpp | 22 ++++++
libc/src/stdlib/strtoull_l.h | 22 ++++++
libc/src/string/CMakeLists.txt | 22 ++++++
libc/src/string/strcoll_l.cpp | 22 ++++++
libc/src/string/strcoll_l.h | 20 +++++
libc/src/string/strxfrm_l.cpp | 23 ++++++
libc/src/string/strxfrm_l.h | 23 ++++++
61 files changed, 1323 insertions(+), 1 deletion(-)
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/src/ctype/isdigit_l.cpp
create mode 100644 libc/src/ctype/isdigit_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/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
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/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/src/stdlib/strtod_l.cpp
create mode 100644 libc/src/stdlib/strtod_l.h
create mode 100644 libc/src/stdlib/strtof_l.cpp
create mode 100644 libc/src/stdlib/strtof_l.h
create mode 100644 libc/src/stdlib/strtold_l.cpp
create mode 100644 libc/src/stdlib/strtold_l.h
create mode 100644 libc/src/stdlib/strtoll_l.cpp
create mode 100644 libc/src/stdlib/strtoll_l.h
create mode 100644 libc/src/stdlib/strtoull_l.cpp
create mode 100644 libc/src/stdlib/strtoull_l.h
create mode 100644 libc/src/string/strcoll_l.cpp
create mode 100644 libc/src/string/strcoll_l.h
create mode 100644 libc/src/string/strxfrm_l.cpp
create mode 100644 libc/src/string/strxfrm_l.h
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 940df63e3912b..8119cd6d300fe 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -17,6 +17,14 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.ctype.tolower
libc.src.ctype.toupper
+ # ctype.h localized entrypoints
+ libc.src.ctype.isdigit_l
+ libc.src.ctype.isxdigit_l
+ libc.src.ctype.islower_l
+ libc.src.ctype.isupper_l
+ libc.src.ctype.tolower_l
+ libc.src.ctype.toupper_l
+
# errno.h entrypoints
libc.src.errno.errno
@@ -85,6 +93,10 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strtok
libc.src.string.strtok_r
+ # string.h localized entrypoints
+ libc.src.string.strxfrm_l
+ libc.src.string.strcoll_l
+
# inttypes.h entrypoints
libc.src.inttypes.imaxabs
libc.src.inttypes.imaxdiv
@@ -194,6 +206,13 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdlib.malloc
libc.src.stdlib.realloc
+ # stdlib.h localized entrypoints
+ libc.src.stdlib.strtof_l
+ libc.src.stdlib.strtod_l
+ libc.src.stdlib.strtold_l
+ libc.src.stdlib.strtoull_l
+ libc.src.stdlib.strtoll_l
+
# stdio.h entrypoints
libc.src.stdio.fdopen
#libc.src.stdio.fscanf
@@ -308,6 +327,14 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.unlink
libc.src.unistd.unlinkat
libc.src.unistd.write
+
+ # locale.h entrypoints
+ libc.src.locale.duplocale
+ libc.src.locale.freelocale
+ libc.src.locale.localeconv
+ libc.src.locale.newlocale
+ libc.src.locale.setlocale
+ libc.src.locale.uselocale
)
set(TARGET_LIBM_ENTRYPOINTS
diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt
index 7d25877cefcc8..48716f8e2b404 100644
--- a/libc/config/linux/aarch64/headers.txt
+++ b/libc/config/linux/aarch64/headers.txt
@@ -31,4 +31,6 @@ set(TARGET_PUBLIC_HEADERS
libc.include.sys_ioctl
# Disabled due to epoll_wait syscalls not being available on this platform.
# libc.include.sys_epoll
+
+ libc.include.locale
)
diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index eb0090c80b0da..ae94e2cf4b2c8 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -308,3 +308,10 @@ def SearchAPI : PublicAPI<"search.h"> {
def SysStatvfsAPI : PublicAPI<"sys/statvfs.h"> {
let Types = ["fsblkcnt_t", "fsfilcnt_t", "struct statvfs"];
}
+
+def LocaleAPI : PublicAPI<"locale.h"> {
+ let Types = [
+ "struct lconv",
+ "locale_t"
+ ];
+}
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 09f04fb31dfd8..0b92b751d6c70 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -17,6 +17,14 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.ctype.tolower
libc.src.ctype.toupper
+ # ctype.h localized entrypoints
+ libc.src.ctype.isdigit_l
+ libc.src.ctype.isxdigit_l
+ libc.src.ctype.islower_l
+ libc.src.ctype.isupper_l
+ libc.src.ctype.tolower_l
+ libc.src.ctype.toupper_l
+
# errno.h entrypoints
libc.src.errno.errno
@@ -87,6 +95,10 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strtok_r
libc.src.string.strxfrm
+ # string.h localized entrypoints
+ libc.src.string.strxfrm_l
+ libc.src.string.strcoll_l
+
# inttypes.h entrypoints
libc.src.inttypes.imaxabs
libc.src.inttypes.imaxdiv
@@ -199,6 +211,13 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdlib.malloc
libc.src.stdlib.realloc
+ # stdlib.h localized entrypoints
+ libc.src.stdlib.strtof_l
+ libc.src.stdlib.strtod_l
+ libc.src.stdlib.strtold_l
+ libc.src.stdlib.strtoull_l
+ libc.src.stdlib.strtoll_l
+
# stdio.h entrypoints
libc.src.stdio.fdopen
libc.src.stdio.fileno
@@ -330,6 +349,14 @@ set(TARGET_LIBC_ENTRYPOINTS
# wchar.h entrypoints
libc.src.wchar.wctob
+
+ # locale.h entrypoints
+ libc.src.locale.duplocale
+ libc.src.locale.freelocale
+ libc.src.locale.localeconv
+ libc.src.locale.newlocale
+ libc.src.locale.setlocale
+ libc.src.locale.uselocale
)
set(TARGET_LIBM_ENTRYPOINTS
diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index 44d640b75e2bf..211354e20ad47 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -49,4 +49,6 @@ set(TARGET_PUBLIC_HEADERS
libc.include.sys_types
libc.include.sys_utsname
libc.include.sys_wait
+
+ libc.include.locale
)
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 3ab7817d8568b..e47d0e81d5ec5 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -199,6 +199,8 @@ add_gen_header(
.llvm-libc-types.struct_timespec
.llvm-libc-types.struct_timeval
.llvm-libc-types.clockid_t
+ .llvm-libc-types.size_t
+ .llvm-libc-types.locale_t
)
add_gen_header(
@@ -358,6 +360,17 @@ add_gen_header(
.llvm-libc-types.posix_spawn_file_actions_t
)
+add_gen_header(
+ locale
+ DEF_FILE locale.h.def
+ GEN_HDR locale.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-types.struct_lconv
+ .llvm-libc-types.locale_t
+ .llvm-libc-macros.locale_macros
+)
+
# TODO: Not all platforms will have a include/sys directory. Add the sys
# directory and the targets for sys/*.h files conditional to the OS requiring
# them.
diff --git a/libc/include/ctype.h.def b/libc/include/ctype.h.def
index a9bb786931ead..a6fc61a61fced 100644
--- a/libc/include/ctype.h.def
+++ b/libc/include/ctype.h.def
@@ -10,6 +10,7 @@
#define LLVM_LIBC_CTYPE_H
#include "__llvm-libc-common.h"
+#include "llvm-libc-types/locale_t.h"
%%public_api()
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index f6af11abd4dd7..05e1eb574f203 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -277,3 +277,9 @@ add_macro_header(
HDR
stdckdint-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..afc3fdbfdbd53
--- /dev/null
+++ b/libc/include/llvm-libc-macros/locale-macros.h
@@ -0,0 +1,30 @@
+//===-- 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
+
+// HACK(@izaakschroeder): Stubs
+#define LC_ALL 0
+#define LC_COLLATE 0
+#define LC_CTYPE 0
+#define LC_MESSAGES 0
+#define LC_MONETARY 0
+#define LC_NUMERIC 0
+#define LC_TIME 0
+
+// HACK(@izaakschroeder): Stubs
+#define LC_ALL_MASK 0
+#define LC_COLLATE_MASK 0
+#define LC_CTYPE_MASK 0
+#define LC_MESSAGES_MASK 0
+#define LC_MONETARY_MASK 0
+#define LC_NUMERIC_MASK 0
+#define LC_TIME_MASK 0
+
+#endif // LLVM_LIBC_MACROS_LOCALE_MACROS_H
diff --git a/libc/include/llvm-libc-macros/stdlib-macros.h b/libc/include/llvm-libc-macros/stdlib-macros.h
index 5fcbfef97b328..f53328b3d9e99 100644
--- a/libc/include/llvm-libc-macros/stdlib-macros.h
+++ b/libc/include/llvm-libc-macros/stdlib-macros.h
@@ -19,4 +19,8 @@
#define RAND_MAX 2147483647
+// N.B. If current thread is utf8 then this is 4
+// otherwise it is 1. Leaving at 4 to be safe.
+#define MB_CUR_MAX 4
+
#endif // LLVM_LIBC_MACROS_STDLIB_MACROS_H
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index d8b975572e0dd..5d579c832954d 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -89,6 +89,8 @@ add_header(thrd_t HDR thrd_t.h DEPENDS .__thread_type)
add_header(tss_t HDR tss_t.h)
add_header(tss_dtor_t HDR tss_dtor_t.h)
add_header(__atexithandler_t HDR __atexithandler_t.h)
+add_header(struct_lconv HDR struct_lconv.h)
+add_header(locale_t HDR locale_t.h)
add_header(speed_t HDR speed_t.h)
add_header(tcflag_t HDR tcflag_t.h)
add_header(struct_termios HDR struct_termios.h DEPENDS .cc_t .speed_t .tcflag_t)
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..35b0f9756eaef
--- /dev/null
+++ b/libc/include/llvm-libc-types/locale_t.h
@@ -0,0 +1,18 @@
+
+//===-- 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
+
+// HACK(@izaakschroeder): Placeholder.
+// NOTE: According to `libcxx` the `locale_t` type has to be at least
+// coercible to a `bool`.
+typedef void *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..27dd7048ec38b
--- /dev/null
+++ b/libc/include/llvm-libc-types/struct_lconv.h
@@ -0,0 +1,39 @@
+//===-- Definition of type struct 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_STRUCT_LCONV_H
+#define LLVM_LIBC_TYPES_STRUCT_LCONV_H
+
+struct lconv {
+ char *currency_symbol;
+ char *decimal_point;
+ char *grouping;
+ char *int_curr_symbol;
+ char *mon_decimal_point;
+ char *mon_grouping;
+ char *mon_thousands_sep;
+ char *negative_sign;
+ char *positive_sign;
+ char *thousands_sep;
+ char frac_digits;
+ char int_frac_digits;
+ char int_p_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_cs_precedes;
+ char int_n_sep_by_space;
+ char int_n_sign_posn;
+ char int_p_sign_posn;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char n_sign_posn;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char p_sign_posn;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_LCONV_H
diff --git a/libc/include/locale.h.def b/libc/include/locale.h.def
new file mode 100644
index 0000000000000..656344031d927
--- /dev/null
+++ b/libc/include/locale.h.def
@@ -0,0 +1,18 @@
+//===-- 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-macros/locale-macros.h"
+#include "llvm-libc-types/locale_t.h"
+#include "llvm-libc-types/struct_lconv.h"
+
+%%public_api()
+
+#endif // LLVM_LIBC_LINK_H
diff --git a/libc/include/stdlib.h.def b/libc/include/stdlib.h.def
index d523f7a53024a..34a11d4e78a77 100644
--- a/libc/include/stdlib.h.def
+++ b/libc/include/stdlib.h.def
@@ -11,6 +11,7 @@
#include "__llvm-libc-common.h"
#include "llvm-libc-macros/stdlib-macros.h"
+#include "llvm-libc-types/locale_t.h"
%%public_api()
diff --git a/libc/include/time.h.def b/libc/include/time.h.def
index 2355e8822fad7..f23488720bac4 100644
--- a/libc/include/time.h.def
+++ b/libc/include/time.h.def
@@ -11,6 +11,8 @@
#include "__llvm-libc-common.h"
#include "llvm-libc-macros/time-macros.h"
+#include "llvm-libc-types/size_t.h"
+#include "llvm-libc-types/locale_t.h"
%%public_api()
diff --git a/libc/spec/posix.td b/libc/spec/posix.td
index d14047548e104..565db1cc4ef35 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -21,6 +21,10 @@ def PThreadOnceT : NamedType<"pthread_once_t">;
def PThreadOnceTPtr : PtrType<PThreadOnceT>;
def PThreadOnceCallback : NamedType<"__pthread_once_func_t">;
+def StructLconv : NamedType<"struct lconv">;
+def StructLconvPtr : PtrType<StructLconv>;
+def LocaleT : NamedType<"locale_t">;
+
def InoT : NamedType<"ino_t">;
def UidT : NamedType<"uid_t">;
def GidT : NamedType<"gid_t">;
@@ -1686,12 +1690,65 @@ def POSIX : StandardSpec<"POSIX"> {
[] // Functions
>;
+ HeaderSpec Locale = HeaderSpec<
+ "locale.h",
+ [], // Macros
+ [LocaleT, StructLconv], // Types
+ [], // Enumerations
+ [
+ FunctionSpec<
+ "duplocale",
+ RetValSpec<LocaleT>,
+ [
+ ArgSpec<LocaleT>
+ ]
+ >,
+ FunctionSpec<
+ "freelocale",
+ RetValSpec<VoidType>,
+ [
+ ArgSpec<LocaleT>
+ ]
+ >,
+ FunctionSpec<
+ "localeconv",
+ RetValSpec<StructLconvPtr>,
+ []
+ >,
+ FunctionSpec<
+ "newlocale",
+ RetValSpec<LocaleT>,
+ [
+ ArgSpec<IntType>,
+ ArgSpec<ConstCharPtr>,
+ ArgSpec<LocaleT>
+ ]
+ >,
+ FunctionSpec<
+ "setlocale",
+ RetValSpec<CharPtr>,
+ [
+ ArgSpec<IntType>,
+ ArgSpec<ConstCharPtr>
+ ]
+ >,
+ FunctionSpec<
+ "uselocale",
+ RetValSpec<LocaleT>,
+ [
+ ArgSpec<LocaleT>
+ ]
+ >
+ ] // Functions
+ >;
+
let Headers = [
ArpaInet,
CType,
Dirent,
Errno,
FCntl,
+ Locale,
PThread,
Sched,
Signal,
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 9ff40bf76700c..ecea09f8af05c 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -2,12 +2,14 @@ def StdC : StandardSpec<"stdc"> {
NamedType StructTmType = NamedType<"struct tm">;
PtrType StructTmPtr = PtrType<StructTmType>;
+
PtrType TimeTTypePtr = PtrType<TimeTType>;
NamedType ClockT = NamedType<"clock_t">;
NamedType DivTType = NamedType<"div_t">;
NamedType LDivTType = NamedType<"ldiv_t">;
NamedType LLDivTType = NamedType<"lldiv_t">;
+ NamedType LocaleTType = NamedType<"locale_t">;
NamedType JmpBuf = NamedType<"jmp_buf">;
@@ -107,6 +109,36 @@ def StdC : StandardSpec<"stdc"> {
RetValSpec<IntType>,
[ArgSpec<IntType>]
>,
+ FunctionSpec<
+ "isdigit_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleTType>]
+ >,
+ FunctionSpec<
+ "isxdigit_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleTType>]
+ >,
+ FunctionSpec<
+ "tolower_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleTType>]
+ >,
+ FunctionSpec<
+ "toupper_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleTType>]
+ >,
+ FunctionSpec<
+ "islower_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleTType>]
+ >,
+ FunctionSpec<
+ "isupper_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleTType>]
+ >,
]
>;
@@ -1139,6 +1171,29 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"strtoul", RetValSpec<UnsignedLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
FunctionSpec<"strtoull", RetValSpec<UnsignedLongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
+
+ FunctionSpec<"strtof_l", RetValSpec<FloatType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<LocaleTType>]>,
+ FunctionSpec<"strtod_l", RetValSpec<DoubleType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<LocaleTType>]>,
+ FunctionSpec<"strtold_l", RetValSpec<LongDoubleType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<LocaleTType>]>,
+ FunctionSpec<"strtol_l", RetValSpec<LongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleTType>]>,
+ FunctionSpec<"strtoll_l", RetValSpec<LongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleTType>]>,
+ FunctionSpec<"strtoul_l", RetValSpec<UnsignedLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleTType>]>,
+ FunctionSpec<"strtoull_l", RetValSpec<UnsignedLongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleTType>]>,
+
+ FunctionSpec<
+ "strxfrm_l",
+ RetValSpec<SizeTType>,
+ [ArgSpec<CharRestrictedPtr>,
+ ArgSpec<ConstCharRestrictedPtr>,
+ ArgSpec<SizeTType>,
+ ArgSpec<LocaleTType>]
+ >,
+ FunctionSpec<
+ "strcoll_l",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstCharPtr>, ArgSpec<ConstCharPtr>, ArgSpec<LocaleTType>]
+ >,
+
FunctionSpec<"malloc", RetValSpec<VoidPtr>, [ArgSpec<SizeTType>]>,
FunctionSpec<"calloc", RetValSpec<VoidPtr>, [ArgSpec<SizeTType>, ArgSpec<SizeTType>]>,
FunctionSpec<"realloc", RetValSpec<VoidPtr>, [ArgSpec<VoidPtr>, ArgSpec<SizeTType>]>,
@@ -1439,7 +1494,7 @@ def StdC : StandardSpec<"stdc"> {
"mktime",
RetValSpec<TimeTType>,
[ArgSpec<StructTmPtr>]
- >,
+ >,
FunctionSpec<
"time",
RetValSpec<TimeTType>,
diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 09b16be1e2d42..00dc2bba141aa 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -4,6 +4,7 @@ add_subdirectory(ctype)
add_subdirectory(errno)
add_subdirectory(fenv)
add_subdirectory(inttypes)
+add_subdirectory(locale)
add_subdirectory(math)
add_subdirectory(stdbit)
add_subdirectory(stdfix)
diff --git a/libc/src/ctype/CMakeLists.txt b/libc/src/ctype/CMakeLists.txt
index ae4eec9615dc1..19e5ef609e93c 100644
--- a/libc/src/ctype/CMakeLists.txt
+++ b/libc/src/ctype/CMakeLists.txt
@@ -146,3 +146,76 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.ctype_utils
)
+
+add_entrypoint_object(
+ isdigit_l
+ SRCS
+ isdigit_l.cpp
+ HDRS
+ isdigit_l.h
+ DEPENDS
+ libc.src.ctype.isdigit
+ libc.include.llvm-libc-types.locale_t
+ libc.src.__support.ctype_utils
+)
+
+add_entrypoint_object(
+ isxdigit_l
+ SRCS
+ isxdigit_l.cpp
+ HDRS
+ isxdigit_l.h
+ DEPENDS
+ libc.src.ctype.isxdigit
+ libc.include.llvm-libc-types.locale_t
+ libc.src.__support.ctype_utils
+)
+
+
+add_entrypoint_object(
+ islower_l
+ SRCS
+ islower_l.cpp
+ HDRS
+ islower_l.h
+ DEPENDS
+ libc.src.ctype.islower
+ libc.include.llvm-libc-types.locale_t
+ libc.src.__support.ctype_utils
+)
+
+add_entrypoint_object(
+ isupper_l
+ SRCS
+ isupper_l.cpp
+ HDRS
+ isupper_l.h
+ DEPENDS
+ libc.src.ctype.isupper
+ libc.include.llvm-libc-types.locale_t
+ libc.src.__support.ctype_utils
+)
+
+add_entrypoint_object(
+ tolower_l
+ SRCS
+ tolower_l.cpp
+ HDRS
+ tolower_l.h
+ DEPENDS
+ libc.src.ctype.tolower
+ libc.include.llvm-libc-types.locale_t
+ libc.src.__support.ctype_utils
+)
+
+add_entrypoint_object(
+ toupper_l
+ SRCS
+ toupper_l.cpp
+ HDRS
+ toupper_l.h
+ DEPENDS
+ libc.src.ctype.toupper
+ libc.include.llvm-libc-types.locale_t
+ libc.src.__support.ctype_utils
+)
diff --git a/libc/src/ctype/isdigit_l.cpp b/libc/src/ctype/isdigit_l.cpp
new file mode 100644
index 0000000000000..5ae615177ebc3
--- /dev/null
+++ b/libc/src/ctype/isdigit_l.cpp
@@ -0,0 +1,17 @@
+//===-- 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/ctype/isdigit.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, isdigit_l, (int c, locale_t)) { return isdigit(c); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/ctype/isdigit_l.h b/libc/src/ctype/isdigit_l.h
new file mode 100644
index 0000000000000..eca38c198b816
--- /dev/null
+++ b/libc/src/ctype/isdigit_l.h
@@ -0,0 +1,20 @@
+//===-- 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_L_H
+#define LLVM_LIBC_SRC_CTYPE_ISDIGIT_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+int isdigit_l(int c, locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_CTYPE_ISDIGIT_L_H
diff --git a/libc/src/ctype/islower_l.cpp b/libc/src/ctype/islower_l.cpp
new file mode 100644
index 0000000000000..2e4cfcb7560a7
--- /dev/null
+++ b/libc/src/ctype/islower_l.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of islower_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/islower_l.h"
+#include "src/ctype/islower.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO: Currently restricted to default locale.
+// These should be extended using locale information.
+LLVM_LIBC_FUNCTION(int, islower_l, (int c, locale_t)) { return islower(c); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/ctype/islower_l.h b/libc/src/ctype/islower_l.h
new file mode 100644
index 0000000000000..dee277ce9af97
--- /dev/null
+++ b/libc/src/ctype/islower_l.h
@@ -0,0 +1,20 @@
+//===-- 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_L_H
+#define LLVM_LIBC_SRC_CTYPE_ISLOWER_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+int islower_l(int c, locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_CTYPE_ISLOWER_L_H
diff --git a/libc/src/ctype/isupper_l.cpp b/libc/src/ctype/isupper_l.cpp
new file mode 100644
index 0000000000000..38a8a90717082
--- /dev/null
+++ b/libc/src/ctype/isupper_l.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of isupper_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/isupper_l.h"
+#include "src/ctype/isupper.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO: Currently restricted to default locale.
+// These should be extended using locale information.
+LLVM_LIBC_FUNCTION(int, isupper_l, (int c, locale_t)) { return isupper(c); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/ctype/isupper_l.h b/libc/src/ctype/isupper_l.h
new file mode 100644
index 0000000000000..fbd49c97cb7fa
--- /dev/null
+++ b/libc/src/ctype/isupper_l.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for isupper -------------------------*-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_L_H
+#define LLVM_LIBC_SRC_CTYPE_ISUPPER_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+int isupper_l(int c, locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_CTYPE_ISUPPER_L_H
diff --git a/libc/src/ctype/isxdigit_l.cpp b/libc/src/ctype/isxdigit_l.cpp
new file mode 100644
index 0000000000000..8e1333331ec74
--- /dev/null
+++ b/libc/src/ctype/isxdigit_l.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of isxdigit_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/isxdigit_l.h"
+#include "src/__support/ctype_utils.h"
+#include "src/ctype/isxdigit.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO: Currently restricted to default locale.
+// These should be extended using locale information.
+LLVM_LIBC_FUNCTION(int, isxdigit_l, (int c, locale_t)) { return isxdigit(c); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/ctype/isxdigit_l.h b/libc/src/ctype/isxdigit_l.h
new file mode 100644
index 0000000000000..875f584ba0a10
--- /dev/null
+++ b/libc/src/ctype/isxdigit_l.h
@@ -0,0 +1,20 @@
+//===-- 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_L_H
+#define LLVM_LIBC_SRC_CTYPE_ISXDIGIT_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+int isxdigit_l(int c, locale_t);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_CTYPE_ISXDIGIT_L_H
diff --git a/libc/src/ctype/tolower_l.cpp b/libc/src/ctype/tolower_l.cpp
new file mode 100644
index 0000000000000..c89c6d7038138
--- /dev/null
+++ b/libc/src/ctype/tolower_l.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of tolower_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/tolower_l.h"
+#include "src/ctype/tolower.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO: Currently restricted to default locale.
+// These should be extended using locale information.
+LLVM_LIBC_FUNCTION(int, tolower_l, (int c, locale_t)) { return tolower(c); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/ctype/tolower_l.h b/libc/src/ctype/tolower_l.h
new file mode 100644
index 0000000000000..624526dbe8f30
--- /dev/null
+++ b/libc/src/ctype/tolower_l.h
@@ -0,0 +1,20 @@
+//===-- 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_L_H
+#define LLVM_LIBC_SRC_CTYPE_TOLOWER_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+int tolower_l(int c, locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_CTYPE_TOLOWER_L_H
diff --git a/libc/src/ctype/toupper_l.cpp b/libc/src/ctype/toupper_l.cpp
new file mode 100644
index 0000000000000..59ab613ffa861
--- /dev/null
+++ b/libc/src/ctype/toupper_l.cpp
@@ -0,0 +1,21 @@
+//===-- 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/ctype/toupper.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO: Currently restricted to default locale.
+// These should be extended using locale information.
+LLVM_LIBC_FUNCTION(int, toupper_l, (int c, locale_t)) { return toupper(c); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/ctype/toupper_l.h b/libc/src/ctype/toupper_l.h
new file mode 100644
index 0000000000000..22a6b5c968b63
--- /dev/null
+++ b/libc/src/ctype/toupper_l.h
@@ -0,0 +1,20 @@
+//===-- 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_L_H
+#define LLVM_LIBC_SRC_CTYPE_TOUPPER_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+int toupper_l(int c, locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_CTYPE_TOUPPER_L_H
diff --git a/libc/src/locale/CMakeLists.txt b/libc/src/locale/CMakeLists.txt
new file mode 100644
index 0000000000000..be955c39f496f
--- /dev/null
+++ b/libc/src/locale/CMakeLists.txt
@@ -0,0 +1,60 @@
+add_entrypoint_object(
+ duplocale
+ SRCS
+ duplocale.cpp
+ HDRS
+ duplocale.h
+ DEPENDS
+ libc.src.__support.common
+)
+
+add_entrypoint_object(
+ freelocale
+ SRCS
+ freelocale.cpp
+ HDRS
+ freelocale.h
+ DEPENDS
+ libc.src.__support.common
+)
+
+add_entrypoint_object(
+ localeconv
+ SRCS
+ localeconv.cpp
+ HDRS
+ localeconv.h
+ DEPENDS
+ libc.src.__support.common
+ libc.include.limits
+)
+
+add_entrypoint_object(
+ newlocale
+ SRCS
+ newlocale.cpp
+ HDRS
+ newlocale.h
+ DEPENDS
+ libc.src.__support.common
+)
+
+add_entrypoint_object(
+ setlocale
+ SRCS
+ setlocale.cpp
+ HDRS
+ setlocale.h
+ DEPENDS
+ libc.src.__support.common
+)
+
+add_entrypoint_object(
+ uselocale
+ SRCS
+ uselocale.cpp
+ HDRS
+ uselocale.h
+ DEPENDS
+ libc.src.__support.common
+)
diff --git a/libc/src/locale/duplocale.cpp b/libc/src/locale/duplocale.cpp
new file mode 100644
index 0000000000000..3c0a0f668856c
--- /dev/null
+++ b/libc/src/locale/duplocale.cpp
@@ -0,0 +1,16 @@
+//===-- 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 "duplocale.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(locale_t, duplocale, (locale_t locale)) { return locale; }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/locale/duplocale.h b/libc/src/locale/duplocale.h
new file mode 100644
index 0000000000000..87a613beada09
--- /dev/null
+++ b/libc/src/locale/duplocale.h
@@ -0,0 +1,20 @@
+//===-- 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 "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+locale_t duplocale(locale_t);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_LINK_DL_ITERATE_PHDR_H
diff --git a/libc/src/locale/freelocale.cpp b/libc/src/locale/freelocale.cpp
new file mode 100644
index 0000000000000..317b6cb0002df
--- /dev/null
+++ b/libc/src/locale/freelocale.cpp
@@ -0,0 +1,18 @@
+//===-- 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 "freelocale.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(void, freelocale, (locale_t)) {
+ // ...
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/locale/freelocale.h b/libc/src/locale/freelocale.h
new file mode 100644
index 0000000000000..eec66b618ebe7
--- /dev/null
+++ b/libc/src/locale/freelocale.h
@@ -0,0 +1,20 @@
+//===-- 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 "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+void freelocale(locale_t);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_LOCALE_FREELOCALE_H
diff --git a/libc/src/locale/localeconv.cpp b/libc/src/locale/localeconv.cpp
new file mode 100644
index 0000000000000..fd9a081198498
--- /dev/null
+++ b/libc/src/locale/localeconv.cpp
@@ -0,0 +1,46 @@
+//===-- 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 "localeconv.h"
+#include "src/__support/common.h"
+#include <limits.h>
+
+namespace LIBC_NAMESPACE {
+
+static const struct lconv posix_lconv = {
+ .currency_symbol = const_cast<char *>(""),
+ .decimal_point = const_cast<char *>("."),
+ .grouping = const_cast<char *>(""),
+ .int_curr_symbol = const_cast<char *>(""),
+ .mon_decimal_point = const_cast<char *>(""),
+ .mon_grouping = const_cast<char *>(""),
+ .mon_thousands_sep = const_cast<char *>(""),
+ .negative_sign = const_cast<char *>(""),
+ .positive_sign = const_cast<char *>(""),
+ .thousands_sep = const_cast<char *>(""),
+ .frac_digits = CHAR_MAX,
+ .int_frac_digits = CHAR_MAX,
+ .int_p_cs_precedes = CHAR_MAX,
+ .int_p_sep_by_space = CHAR_MAX,
+ .int_n_cs_precedes = CHAR_MAX,
+ .int_n_sep_by_space = CHAR_MAX,
+ .int_n_sign_posn = CHAR_MAX,
+ .int_p_sign_posn = CHAR_MAX,
+ .n_cs_precedes = CHAR_MAX,
+ .n_sep_by_space = CHAR_MAX,
+ .n_sign_posn = CHAR_MAX,
+ .p_cs_precedes = CHAR_MAX,
+ .p_sep_by_space = CHAR_MAX,
+ .p_sign_posn = CHAR_MAX,
+};
+
+LLVM_LIBC_FUNCTION(struct lconv *, localeconv, ()) {
+ return const_cast<struct lconv *>(&posix_lconv);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/locale/localeconv.h b/libc/src/locale/localeconv.h
new file mode 100644
index 0000000000000..e095be7334365
--- /dev/null
+++ b/libc/src/locale/localeconv.h
@@ -0,0 +1,20 @@
+//===-- 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 "include/llvm-libc-types/struct_lconv.h"
+
+namespace LIBC_NAMESPACE {
+
+struct lconv *localeconv(void);
+
+} // namespace LIBC_NAMESPACE
+
+#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..332f40bd7ba8f
--- /dev/null
+++ b/libc/src/locale/newlocale.cpp
@@ -0,0 +1,18 @@
+//===-- 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 "newlocale.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(locale_t, newlocale, (int, const char *, locale_t locale)) {
+ return locale;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/locale/newlocale.h b/libc/src/locale/newlocale.h
new file mode 100644
index 0000000000000..d8a0f66e7f060
--- /dev/null
+++ b/libc/src/locale/newlocale.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for newlocale ---------------------*- 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_NEWLOCALE_H
+#define LLVM_LIBC_SRC_LOCALE_NEWLOCALE_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+locale_t newlocale(int, const char *, locale_t);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_LOCALE_NEWLOCALE_H
diff --git a/libc/src/locale/setlocale.cpp b/libc/src/locale/setlocale.cpp
new file mode 100644
index 0000000000000..9a5aba412776c
--- /dev/null
+++ b/libc/src/locale/setlocale.cpp
@@ -0,0 +1,18 @@
+//===-- 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 "setlocale.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(char *, setlocale, (int, const char *)) {
+ return const_cast<char *>("unsupported");
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/locale/setlocale.h b/libc/src/locale/setlocale.h
new file mode 100644
index 0000000000000..a438c8426a2b7
--- /dev/null
+++ b/libc/src/locale/setlocale.h
@@ -0,0 +1,18 @@
+//===-- 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
+
+namespace LIBC_NAMESPACE {
+
+char *setlocale(int, const char *);
+
+} // namespace LIBC_NAMESPACE
+
+#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..b614313ac7f78
--- /dev/null
+++ b/libc/src/locale/uselocale.cpp
@@ -0,0 +1,16 @@
+//===-- 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 "uselocale.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(locale_t, uselocale, (locale_t locale)) { return locale; }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/locale/uselocale.h b/libc/src/locale/uselocale.h
new file mode 100644
index 0000000000000..48abb54cbfcfe
--- /dev/null
+++ b/libc/src/locale/uselocale.h
@@ -0,0 +1,20 @@
+//===-- 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 "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+locale_t uselocale(locale_t);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_LOCALE_USELOCALE_H
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 677bf358c82c4..4fc93c7bcdb91 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -516,3 +516,63 @@ add_entrypoint_object(
DEPENDS
.${LIBC_TARGET_OS}.abort
)
+
+add_entrypoint_object(
+ strtof_l
+ SRCS
+ strtof_l.cpp
+ HDRS
+ strtof_l.h
+ DEPENDS
+ libc.src.stdlib.strtof
+ libc.src.errno.errno
+ libc.include.llvm-libc-types.locale_t
+)
+
+add_entrypoint_object(
+ strtod_l
+ SRCS
+ strtod_l.cpp
+ HDRS
+ strtod_l.h
+ DEPENDS
+ libc.src.stdlib.strtod
+ libc.src.errno.errno
+ libc.include.llvm-libc-types.locale_t
+)
+
+add_entrypoint_object(
+ strtold_l
+ SRCS
+ strtold_l.cpp
+ HDRS
+ strtold_l.h
+ DEPENDS
+ libc.src.stdlib.strtold
+ libc.src.errno.errno
+ libc.include.llvm-libc-types.locale_t
+)
+
+add_entrypoint_object(
+ strtoull_l
+ SRCS
+ strtoull_l.cpp
+ HDRS
+ strtoull_l.h
+ DEPENDS
+ libc.src.stdlib.strtoull
+ libc.src.errno.errno
+ libc.include.llvm-libc-types.locale_t
+)
+
+add_entrypoint_object(
+ strtoll_l
+ SRCS
+ strtoll_l.cpp
+ HDRS
+ strtoll_l.h
+ DEPENDS
+ libc.src.stdlib.strtoll
+ libc.src.errno.errno
+ libc.include.llvm-libc-types.locale_t
+)
diff --git a/libc/src/stdlib/strtod_l.cpp b/libc/src/stdlib/strtod_l.cpp
new file mode 100644
index 0000000000000..898a925d5face
--- /dev/null
+++ b/libc/src/stdlib/strtod_l.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of strtod_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/stdlib/strtod_l.h"
+#include "src/__support/common.h"
+#include "src/stdlib/strtod.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, strtod_l,
+ (const char *__restrict str, char **__restrict str_end,
+ locale_t)) {
+ return strtod(str, str_end);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/strtod_l.h b/libc/src/stdlib/strtod_l.h
new file mode 100644
index 0000000000000..6e130f332e127
--- /dev/null
+++ b/libc/src/stdlib/strtod_l.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for strtod_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_STDLIB_STRTOD_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOD_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+double strtod_l(const char *__restrict str, char **__restrict str_end,
+ locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOD_L_H
diff --git a/libc/src/stdlib/strtof_l.cpp b/libc/src/stdlib/strtof_l.cpp
new file mode 100644
index 0000000000000..c5d25e60be02b
--- /dev/null
+++ b/libc/src/stdlib/strtof_l.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of strtof_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/stdlib/strtof_l.h"
+#include "src/__support/common.h"
+#include "src/stdlib/strtof.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, strtof_l,
+ (const char *__restrict str, char **__restrict str_end,
+ locale_t)) {
+ return strtof(str, str_end);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/strtof_l.h b/libc/src/stdlib/strtof_l.h
new file mode 100644
index 0000000000000..40552ba2d87ef
--- /dev/null
+++ b/libc/src/stdlib/strtof_l.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for strtof_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_STDLIB_STRTOF_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOF_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+float strtof_l(const char *__restrict str, char **__restrict str_end,
+ locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOF_L_H
diff --git a/libc/src/stdlib/strtold_l.cpp b/libc/src/stdlib/strtold_l.cpp
new file mode 100644
index 0000000000000..245356ce08ea6
--- /dev/null
+++ b/libc/src/stdlib/strtold_l.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of strtold_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/stdlib/strtold_l.h"
+#include "src/__support/common.h"
+#include "src/stdlib/strtold.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, strtold_l,
+ (const char *__restrict str, char **__restrict str_end,
+ locale_t)) {
+
+ return strtold(str, str_end);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/strtold_l.h b/libc/src/stdlib/strtold_l.h
new file mode 100644
index 0000000000000..d156f46d50ac9
--- /dev/null
+++ b/libc/src/stdlib/strtold_l.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for strtold_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_STDLIB_STRTOLD_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOLD_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+long double strtold_l(const char *__restrict str, char **__restrict str_end,
+ locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOLD_L_H
diff --git a/libc/src/stdlib/strtoll_l.cpp b/libc/src/stdlib/strtoll_l.cpp
new file mode 100644
index 0000000000000..e3a6c89a2a23d
--- /dev/null
+++ b/libc/src/stdlib/strtoll_l.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of strtoll_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/stdlib/strtoll_l.h"
+#include "src/__support/common.h"
+#include "src/stdlib/strtoll.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long long, strtoll_l,
+ (const char *__restrict str, char **__restrict str_end,
+ int base, locale_t)) {
+
+ return strtoll(str, str_end, base);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/strtoll_l.h b/libc/src/stdlib/strtoll_l.h
new file mode 100644
index 0000000000000..96cab62897039
--- /dev/null
+++ b/libc/src/stdlib/strtoll_l.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for strtoll -----------------------*- 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_STDLIB_STRTOLL_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOLL_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+long long strtoll_l(const char *__restrict str, char **__restrict str_end,
+ int base, locale_t);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOLL_L_H
diff --git a/libc/src/stdlib/strtoull_l.cpp b/libc/src/stdlib/strtoull_l.cpp
new file mode 100644
index 0000000000000..72f8fd011d51f
--- /dev/null
+++ b/libc/src/stdlib/strtoull_l.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of strtoull_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/stdlib/strtoull_l.h"
+#include "src/__support/common.h"
+#include "src/stdlib/strtoull.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(unsigned long long, strtoull_l,
+ (const char *__restrict str, char **__restrict str_end,
+ int base, locale_t)) {
+
+ return strtoull(str, str_end, base);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/strtoull_l.h b/libc/src/stdlib/strtoull_l.h
new file mode 100644
index 0000000000000..6c24ecd3abbb1
--- /dev/null
+++ b/libc/src/stdlib/strtoull_l.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for strtoull_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_STDLIB_STRTOULL_L_H
+#define LLVM_LIBC_SRC_STDLIB_STRTOULL_L_H
+
+#include "include/llvm-libc-types/locale_t.h"
+
+namespace LIBC_NAMESPACE {
+
+unsigned long long strtoull_l(const char *__restrict str,
+ char **__restrict str_end, int base,
+ locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDLIB_STRTOULL_L_H
diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index 56588ffafb86f..794e9206aded4 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -452,6 +452,28 @@ add_entrypoint_object(
.memory_utils.inline_memset
)
+add_entrypoint_object(
+ strcoll_l
+ SRCS
+ strcoll_l.cpp
+ HDRS
+ strcoll_l.h
+ DEPENDS
+ .strcoll
+ libc.include.llvm-libc-types.locale_t
+)
+
+add_entrypoint_object(
+ strxfrm_l
+ SRCS
+ strxfrm_l.cpp
+ HDRS
+ strxfrm_l.h
+ DEPENDS
+ .strxfrm
+ libc.include.llvm-libc-types.locale_t
+)
+
# Helper to define a function with multiple implementations
# - Computes flags to satisfy required/rejected features and arch,
# - Declares an entry point,
diff --git a/libc/src/string/strcoll_l.cpp b/libc/src/string/strcoll_l.cpp
new file mode 100644
index 0000000000000..8bfef08d91619
--- /dev/null
+++ b/libc/src/string/strcoll_l.cpp
@@ -0,0 +1,22 @@
+//===-- 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/string/strcoll.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO: Add support for locales.
+LLVM_LIBC_FUNCTION(int, strcoll_l,
+ (const char *left, const char *right, locale_t)) {
+ return strcoll(left, right);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/string/strcoll_l.h b/libc/src/string/strcoll_l.h
new file mode 100644
index 0000000000000..0eee80125a942
--- /dev/null
+++ b/libc/src/string/strcoll_l.h
@@ -0,0 +1,20 @@
+//===-- 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"
+
+namespace LIBC_NAMESPACE {
+
+int strcoll_l(const char *left, const char *right, locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#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 0000000000000..8e929185a61c6
--- /dev/null
+++ b/libc/src/string/strxfrm_l.cpp
@@ -0,0 +1,23 @@
+//===-- 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/string/strxfrm.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO: Add support for locales.
+LLVM_LIBC_FUNCTION(size_t, strxfrm_l,
+ (char *__restrict dest, const char *__restrict src, size_t n,
+ locale_t)) {
+ return strxfrm(dest, src, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/string/strxfrm_l.h b/libc/src/string/strxfrm_l.h
new file mode 100644
index 0000000000000..d56a6ff073e9b
--- /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 <stddef.h> // For size_t
+
+namespace LIBC_NAMESPACE {
+
+size_t strxfrm_l(char *__restrict dest, const char *__restrict src, size_t n,
+ locale_t locale);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STRING_STRXFRM_L_H
More information about the libc-commits
mailing list