[libc-commits] [libc] 856dadb - [libc] Add `ctype.h` locale variants (#102711)
Joseph Huber via libc-commits
libc-commits at lists.llvm.org
Thu Aug 22 11:52:11 PDT 2024
Author: Joseph Huber
Date: 2024-08-22T13:51:54-05:00
New Revision: 856dadb33c38f4e3be592f11c3d67e7337e288c7
URL: https://github.com/llvm/llvm-project/commit/856dadb33c38f4e3be592f11c3d67e7337e288c7
DIFF: https://github.com/llvm/llvm-project/commit/856dadb33c38f4e3be592f11c3d67e7337e288c7.diff
LOG: [libc] Add `ctype.h` locale variants (#102711)
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.
Added:
libc/src/ctype/isalnum_l.cpp
libc/src/ctype/isalnum_l.h
libc/src/ctype/isalpha_l.cpp
libc/src/ctype/isalpha_l.h
libc/src/ctype/isblank_l.cpp
libc/src/ctype/isblank_l.h
libc/src/ctype/iscntrl_l.cpp
libc/src/ctype/iscntrl_l.h
libc/src/ctype/isdigit_l.cpp
libc/src/ctype/isdigit_l.h
libc/src/ctype/isgraph_l.cpp
libc/src/ctype/isgraph_l.h
libc/src/ctype/islower_l.cpp
libc/src/ctype/islower_l.h
libc/src/ctype/isprint_l.cpp
libc/src/ctype/isprint_l.h
libc/src/ctype/ispunct_l.cpp
libc/src/ctype/ispunct_l.h
libc/src/ctype/isspace_l.cpp
libc/src/ctype/isspace_l.h
libc/src/ctype/isupper_l.cpp
libc/src/ctype/isupper_l.h
libc/src/ctype/isxdigit_l.cpp
libc/src/ctype/isxdigit_l.h
libc/src/ctype/tolower_l.cpp
libc/src/ctype/tolower_l.h
libc/src/ctype/toupper_l.cpp
libc/src/ctype/toupper_l.h
Modified:
libc/config/gpu/entrypoints.txt
libc/config/linux/x86_64/entrypoints.txt
libc/include/CMakeLists.txt
libc/newhdrgen/yaml/ctype.yaml
libc/spec/stdc.td
libc/src/ctype/CMakeLists.txt
libc/src/ctype/isalnum.cpp
libc/src/ctype/isalpha.cpp
libc/src/ctype/isblank.cpp
libc/src/ctype/iscntrl.cpp
libc/src/ctype/isdigit.cpp
libc/src/ctype/isgraph.cpp
libc/src/ctype/islower.cpp
libc/src/ctype/isprint.cpp
libc/src/ctype/ispunct.cpp
libc/src/ctype/isspace.cpp
libc/src/ctype/isupper.cpp
libc/src/ctype/isxdigit.cpp
libc/src/ctype/tolower.cpp
libc/src/ctype/toupper.cpp
Removed:
################################################################################
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 0674f23687c0a5..7b869902074d8e 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 e7c3c7db64abe5..bac1e3cfa85da7 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 8e00c9f1292e81..910f9eea015f27 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 f3108a34d43377..b4823c3e53234a 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 f9573997c65739..402d8c335470ad 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<IntType>,
[ArgSpec<IntType>]
>,
+ FunctionSpec<
+ "isalnum_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "isalpha_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "isblank_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "iscntrl_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "isdigit_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "isgraph_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "islower_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "isprint_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "ispunct_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "isspace_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "isupper_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "isxdigit_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "tolower_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
+ FunctionSpec<
+ "toupper_l",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<LocaleT>]
+ >,
]
>;
diff --git a/libc/src/ctype/CMakeLists.txt b/libc/src/ctype/CMakeLists.txt
index ae4eec9615dc19..8830c1bccf9eaa 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 382553c23a6bfb..54a3e357488790 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<int>(internal::isalnum(static_cast<unsigned>(c)));
}
diff --git a/libc/src/ctype/isalnum_l.cpp b/libc/src/ctype/isalnum_l.cpp
new file mode 100644
index 00000000000000..671d9b75c4c33a
--- /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<int>(internal::isalnum(static_cast<unsigned>(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 00000000000000..5bc892e6c8747e
--- /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 1a63406780b6e0..78b26f6a486eae 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<int>(internal::isalpha(static_cast<unsigned>(c)));
}
diff --git a/libc/src/ctype/isalpha_l.cpp b/libc/src/ctype/isalpha_l.cpp
new file mode 100644
index 00000000000000..0619d979bedf22
--- /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<int>(internal::isalpha(static_cast<unsigned>(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 00000000000000..3591f1175cb9a9
--- /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 a4f33d265bd2dd..e0a20829f86cee 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<int>(c == ' ' || c == '\t');
}
diff --git a/libc/src/ctype/isblank_l.cpp b/libc/src/ctype/isblank_l.cpp
new file mode 100644
index 00000000000000..4f6b0bfac29724
--- /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<int>(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 00000000000000..61ede30ae76775
--- /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 fb582fd6ef0820..2218adfcc33f3b 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<unsigned>(c);
return static_cast<int>(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 00000000000000..83aa480299fadc
--- /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<unsigned>(c);
+ return static_cast<int>(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 00000000000000..7dee44fcd0bebc
--- /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 43c5f1940c7f00..1f711943861f8b 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<int>(internal::isdigit(static_cast<unsigned>(c)));
}
diff --git a/libc/src/ctype/isdigit_l.cpp b/libc/src/ctype/isdigit_l.cpp
new file mode 100644
index 00000000000000..ca981362bfe839
--- /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<int>(internal::isdigit(static_cast<unsigned>(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 00000000000000..abeec3464941a0
--- /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 a5b6e501b5813f..74bb2e75d138e6 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<int>(internal::isgraph(static_cast<unsigned>(c)));
}
diff --git a/libc/src/ctype/isgraph_l.cpp b/libc/src/ctype/isgraph_l.cpp
new file mode 100644
index 00000000000000..cbef6df148aed6
--- /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<int>(internal::isgraph(static_cast<unsigned>(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 00000000000000..d96a4608655092
--- /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 61ccbcc1db413b..831aad32d3a22e 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<int>(internal::islower(static_cast<unsigned>(c)));
}
diff --git a/libc/src/ctype/islower_l.cpp b/libc/src/ctype/islower_l.cpp
new file mode 100644
index 00000000000000..b9be6acc81c992
--- /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<int>(internal::islower(static_cast<unsigned>(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 00000000000000..7d3e2f139602b9
--- /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 42ab9cc8d238a1..349aefe1c17bbd 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<unsigned>(c);
return static_cast<int>((ch - ' ') < 95);
diff --git a/libc/src/ctype/isprint_l.cpp b/libc/src/ctype/isprint_l.cpp
new file mode 100644
index 00000000000000..8f51f7f0e3e94b
--- /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<unsigned>(c);
+ return static_cast<int>((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 00000000000000..bd2ea9354c36a0
--- /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 c1906e3acdd80e..0635294220b9c3 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<unsigned>(c);
return static_cast<int>(!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 00000000000000..e825fbe2001b08
--- /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<unsigned>(c);
+ return static_cast<int>(!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 00000000000000..862daf4836f788
--- /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 f8908493787841..005bf460fc1032 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<int>(internal::isspace(static_cast<unsigned>(c)));
}
diff --git a/libc/src/ctype/isspace_l.cpp b/libc/src/ctype/isspace_l.cpp
new file mode 100644
index 00000000000000..5c46dd68051261
--- /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<int>(internal::isspace(static_cast<unsigned>(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 00000000000000..61bbf127956da7
--- /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 8f929ea1a009e4..965fa336b28b4d 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<int>(internal::isupper(static_cast<unsigned>(c)));
}
diff --git a/libc/src/ctype/isupper_l.cpp b/libc/src/ctype/isupper_l.cpp
new file mode 100644
index 00000000000000..358990261d603f
--- /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<int>(internal::isupper(static_cast<unsigned>(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 00000000000000..9bee7ef8c09f59
--- /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 391c5c53cee1e1..6b730c354db083 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<unsigned>(c);
return static_cast<int>(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 00000000000000..8a5c7d4d28ab1c
--- /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<unsigned>(c);
+ return static_cast<int>(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 00000000000000..ee847eda4eae9a
--- /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 e230428eef2b14..3ecad7bc5d5d54 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 00000000000000..7ccf31617e5925
--- /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 00000000000000..6099b8c813469c
--- /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 97c1ac2c02b8c0..b5a23fc7f588bd 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 00000000000000..f536ff36236160
--- /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 00000000000000..8877c35d492bd8
--- /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
More information about the libc-commits
mailing list