diff options
-rw-r--r-- | libc/config/linux/aarch64/entrypoints.txt | 2 | ||||
-rw-r--r-- | libc/config/linux/api.td | 2 | ||||
-rw-r--r-- | libc/config/linux/x86_64/entrypoints.txt | 2 | ||||
-rw-r--r-- | libc/spec/stdc.td | 10 | ||||
-rw-r--r-- | libc/src/ctype/CMakeLists.txt | 24 | ||||
-rw-r--r-- | libc/src/ctype/ctype_utils.h | 8 | ||||
-rw-r--r-- | libc/src/ctype/islower.cpp | 6 | ||||
-rw-r--r-- | libc/src/ctype/isupper.cpp | 6 | ||||
-rw-r--r-- | libc/src/ctype/tolower.cpp | 24 | ||||
-rw-r--r-- | libc/src/ctype/tolower.h | 18 | ||||
-rw-r--r-- | libc/src/ctype/toupper.cpp | 24 | ||||
-rw-r--r-- | libc/src/ctype/toupper.h | 18 | ||||
-rw-r--r-- | libc/test/src/ctype/CMakeLists.txt | 20 | ||||
-rw-r--r-- | libc/test/src/ctype/tolower_test.cpp | 20 | ||||
-rw-r--r-- | libc/test/src/ctype/toupper_test.cpp | 20 |
15 files changed, 194 insertions, 10 deletions
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 468f2cc69ebe..e1f54bfaa4fd 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -12,6 +12,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.ctype.isspace libc.src.ctype.isupper libc.src.ctype.isxdigit + libc.src.ctype.tolower + libc.src.ctype.toupper # errno.h entrypoints libc.src.errno.__errno_location diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td index 71b592d294a9..151924748dc1 100644 --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -100,6 +100,8 @@ def CTypeAPI : PublicAPI<"ctype.h"> { "isspace", "isupper", "isxdigit", + "tolower", + "toupper", ]; } diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 031812ce32d7..db76c351db7f 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -15,6 +15,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.ctype.isspace libc.src.ctype.isupper libc.src.ctype.isxdigit + libc.src.ctype.tolower + libc.src.ctype.toupper # errno.h entrypoints libc.src.errno.__errno_location diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 892fbb2d3076..ac240ff9576e 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -106,6 +106,16 @@ def StdC : StandardSpec<"stdc"> { RetValSpec<IntType>, [ArgSpec<IntType>] >, + FunctionSpec< + "tolower", + RetValSpec<IntType>, + [ArgSpec<IntType>] + >, + FunctionSpec< + "toupper", + RetValSpec<IntType>, + [ArgSpec<IntType>] + >, ] >; diff --git a/libc/src/ctype/CMakeLists.txt b/libc/src/ctype/CMakeLists.txt index 4356eabf23fe..da8c4403d959 100644 --- a/libc/src/ctype/CMakeLists.txt +++ b/libc/src/ctype/CMakeLists.txt @@ -66,6 +66,8 @@ add_entrypoint_object( islower.cpp HDRS islower.h + DEPENDS + .ctype_utils ) add_entrypoint_object( @@ -100,6 +102,8 @@ add_entrypoint_object( isupper.cpp HDRS isupper.h + DEPENDS + .ctype_utils ) add_entrypoint_object( @@ -111,3 +115,23 @@ add_entrypoint_object( DEPENDS .ctype_utils ) + +add_entrypoint_object( + tolower + SRCS + tolower.cpp + HDRS + tolower.h + DEPENDS + .ctype_utils +) + +add_entrypoint_object( + toupper + SRCS + toupper.cpp + HDRS + toupper.h + DEPENDS + .ctype_utils +) diff --git a/libc/src/ctype/ctype_utils.h b/libc/src/ctype/ctype_utils.h index 787a19ebf132..6238bd32d9f8 100644 --- a/libc/src/ctype/ctype_utils.h +++ b/libc/src/ctype/ctype_utils.h @@ -18,14 +18,18 @@ namespace internal { // of a function call by inlining them. // ------------------------------------------------------ -static inline int isdigit(unsigned ch) { return (ch - '0') < 10; } - static inline int isalpha(unsigned ch) { return (ch | 32) - 'a' < 26; } +static inline int isdigit(unsigned ch) { return (ch - '0') < 10; } + static inline int isalnum(unsigned ch) { return isalpha(ch) || isdigit(ch); } static inline int isgraph(unsigned ch) { return 0x20 < ch && ch < 0x7f; } +static inline int islower(unsigned ch) { return (ch - 'a') < 26; } + +static inline int isupper(unsigned ch) { return (ch - 'A') < 26; } + } // namespace internal } // namespace __llvm_libc diff --git a/libc/src/ctype/islower.cpp b/libc/src/ctype/islower.cpp index df21355f31ac..ae1291b5eda4 100644 --- a/libc/src/ctype/islower.cpp +++ b/libc/src/ctype/islower.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "src/ctype/islower.h" +#include "src/ctype/ctype_utils.h" #include "src/__support/common.h" @@ -14,9 +15,6 @@ namespace __llvm_libc { // TODO: Currently restricted to default locale. // These should be extended using locale information. -int LLVM_LIBC_ENTRYPOINT(islower)(int c) { - const unsigned ch = c; - return (ch - 'a') < 26; -} +int LLVM_LIBC_ENTRYPOINT(islower)(int c) { return internal::islower(c); } } // namespace __llvm_libc diff --git a/libc/src/ctype/isupper.cpp b/libc/src/ctype/isupper.cpp index 57aed961d1e5..9b0e5232f1f9 100644 --- a/libc/src/ctype/isupper.cpp +++ b/libc/src/ctype/isupper.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isupper.h" +#include "src/ctype/ctype_utils.h" #include "src/__support/common.h" @@ -14,9 +15,6 @@ namespace __llvm_libc { // TODO: Currently restricted to default locale. // These should be extended using locale information. -int LLVM_LIBC_ENTRYPOINT(isupper)(int c) { - const unsigned ch = c; - return (ch - 'A') < 26; -} +int LLVM_LIBC_ENTRYPOINT(isupper)(int c) { return internal::isupper(c); } } // namespace __llvm_libc diff --git a/libc/src/ctype/tolower.cpp b/libc/src/ctype/tolower.cpp new file mode 100644 index 000000000000..6fd300680179 --- /dev/null +++ b/libc/src/ctype/tolower.cpp @@ -0,0 +1,24 @@ +//===-- 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.h" +#include "src/ctype/ctype_utils.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +// TODO: Currently restricted to default locale. +// These should be extended using locale information. +int LLVM_LIBC_ENTRYPOINT(tolower)(int c) { + if (internal::isupper(c)) + return c + 'a' - 'A'; + return c; +} + +} // namespace __llvm_libc diff --git a/libc/src/ctype/tolower.h b/libc/src/ctype/tolower.h new file mode 100644 index 000000000000..97e675c55825 --- /dev/null +++ b/libc/src/ctype/tolower.h @@ -0,0 +1,18 @@ +//===-- Implementation header for tolower -------------------------*-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 + +namespace __llvm_libc { + +int tolower(int c); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_CTYPE_TOLOWER_H diff --git a/libc/src/ctype/toupper.cpp b/libc/src/ctype/toupper.cpp new file mode 100644 index 000000000000..8d591c20be67 --- /dev/null +++ b/libc/src/ctype/toupper.cpp @@ -0,0 +1,24 @@ +//===-- Implementation of toupper------------------------------------------===// +// +// 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.h" +#include "src/ctype/ctype_utils.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +// TODO: Currently restricted to default locale. +// These should be extended using locale information. +int LLVM_LIBC_ENTRYPOINT(toupper)(int c) { + if (internal::islower(c)) + return c + 'A' - 'a'; + return c; +} + +} // namespace __llvm_libc diff --git a/libc/src/ctype/toupper.h b/libc/src/ctype/toupper.h new file mode 100644 index 000000000000..a21b0cf79d95 --- /dev/null +++ b/libc/src/ctype/toupper.h @@ -0,0 +1,18 @@ +//===-- Implementation header for toupper -------------------------*-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 + +namespace __llvm_libc { + +int toupper(int c); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_CTYPE_TOUPPER_H diff --git a/libc/test/src/ctype/CMakeLists.txt b/libc/test/src/ctype/CMakeLists.txt index 0d77134b95eb..4141708fc2b4 100644 --- a/libc/test/src/ctype/CMakeLists.txt +++ b/libc/test/src/ctype/CMakeLists.txt @@ -119,3 +119,23 @@ add_libc_unittest( DEPENDS libc.src.ctype.isxdigit ) + +add_libc_unittest( + tolower + SUITE + libc_ctype_unittests + SRCS + tolower_test.cpp + DEPENDS + libc.src.ctype.tolower +) + +add_libc_unittest( + toupper + SUITE + libc_ctype_unittests + SRCS + toupper_test.cpp + DEPENDS + libc.src.ctype.toupper +) diff --git a/libc/test/src/ctype/tolower_test.cpp b/libc/test/src/ctype/tolower_test.cpp new file mode 100644 index 000000000000..096ef969bf63 --- /dev/null +++ b/libc/test/src/ctype/tolower_test.cpp @@ -0,0 +1,20 @@ +//===-- Unittests for 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.h" +#include "utils/UnitTest/Test.h" + +TEST(ToLower, DefaultLocale) { + for (int ch = 0; ch < 255; ++ch) { + // This follows pattern 'A' + 32 = 'a'. + if ('A' <= ch && ch <= 'Z') + EXPECT_EQ(__llvm_libc::tolower(ch), ch + 32); + else + EXPECT_EQ(__llvm_libc::tolower(ch), ch); + } +} diff --git a/libc/test/src/ctype/toupper_test.cpp b/libc/test/src/ctype/toupper_test.cpp new file mode 100644 index 000000000000..4d6a1b3d4f65 --- /dev/null +++ b/libc/test/src/ctype/toupper_test.cpp @@ -0,0 +1,20 @@ +//===-- Unittests for toupper----------------------------------------------===// +// +// 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.h" +#include "utils/UnitTest/Test.h" + +TEST(ToUpper, DefaultLocale) { + for (int ch = 0; ch < 255; ++ch) { + // This follows pattern 'a' - 32 = 'A'. + if ('a' <= ch && ch <= 'z') + EXPECT_EQ(__llvm_libc::toupper(ch), ch - 32); + else + EXPECT_EQ(__llvm_libc::toupper(ch), ch); + } +} |