From e2d4bf6ceca84c2ff515d6bc89da7d40d1c971fb Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Fri, 31 Jul 2020 14:04:36 -0400 Subject: [PATCH] [libc] Add islower and isupper implementation. Reviewed By: sivachandra Differential Revision: https://reviews.llvm.org/D84960 --- libc/config/linux/aarch64/entrypoints.txt | 2 ++ libc/config/linux/api.td | 2 ++ libc/config/linux/x86_64/entrypoints.txt | 2 ++ libc/spec/stdc.td | 10 ++++++++++ libc/src/ctype/CMakeLists.txt | 16 ++++++++++++++++ libc/src/ctype/islower.cpp | 22 ++++++++++++++++++++++ libc/src/ctype/islower.h | 18 ++++++++++++++++++ libc/src/ctype/isupper.cpp | 22 ++++++++++++++++++++++ libc/src/ctype/isupper.h | 18 ++++++++++++++++++ libc/test/src/ctype/CMakeLists.txt | 20 ++++++++++++++++++++ libc/test/src/ctype/isalnum_test.cpp | 12 ++++-------- libc/test/src/ctype/isalpha_test.cpp | 14 +++++--------- libc/test/src/ctype/isdigit_test.cpp | 14 +++++--------- libc/test/src/ctype/islower_test.cpp | 21 +++++++++++++++++++++ libc/test/src/ctype/isupper_test.cpp | 21 +++++++++++++++++++++ 15 files changed, 188 insertions(+), 26 deletions(-) create mode 100644 libc/src/ctype/islower.cpp create mode 100644 libc/src/ctype/islower.h create mode 100644 libc/src/ctype/isupper.cpp create mode 100644 libc/src/ctype/isupper.h create mode 100644 libc/test/src/ctype/islower_test.cpp create mode 100644 libc/test/src/ctype/isupper_test.cpp diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 8d2cc1618946..5f058e611600 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -3,6 +3,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.ctype.isalnum libc.src.ctype.isalpha libc.src.ctype.isdigit + libc.src.ctype.islower + libc.src.ctype.isupper # errno.h entrypoints libc.src.errno.__errno_location diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td index 01e6eab92f01..03d5d66e41e7 100644 --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -91,6 +91,8 @@ def CTypeAPI : PublicAPI<"ctype.h"> { "isalnum", "isalpha", "isdigit", + "islower", + "isupper", ]; } diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 4484f6cbf1a7..5dc1d38455dc 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -6,6 +6,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.ctype.isalnum libc.src.ctype.isalpha libc.src.ctype.isdigit + libc.src.ctype.islower + libc.src.ctype.isupper # errno.h entrypoints libc.src.errno.__errno_location diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index fed24cb2dbdd..4fffc5cdc857 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -61,6 +61,16 @@ def StdC : StandardSpec<"stdc"> { RetValSpec, [ArgSpec] >, + FunctionSpec< + "islower", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "isupper", + RetValSpec, + [ArgSpec] + >, ] >; diff --git a/libc/src/ctype/CMakeLists.txt b/libc/src/ctype/CMakeLists.txt index 53161b8b179f..30995ab2f714 100644 --- a/libc/src/ctype/CMakeLists.txt +++ b/libc/src/ctype/CMakeLists.txt @@ -33,3 +33,19 @@ add_entrypoint_object( DEPENDS .ctype_utils ) + +add_entrypoint_object( + islower + SRCS + islower.cpp + HDRS + islower.h +) + +add_entrypoint_object( + isupper + SRCS + isupper.cpp + HDRS + isupper.h +) diff --git a/libc/src/ctype/islower.cpp b/libc/src/ctype/islower.cpp new file mode 100644 index 000000000000..df21355f31ac --- /dev/null +++ b/libc/src/ctype/islower.cpp @@ -0,0 +1,22 @@ +//===-- 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.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(islower)(int c) { + const unsigned ch = c; + return (ch - 'a') < 26; +} + +} // namespace __llvm_libc diff --git a/libc/src/ctype/islower.h b/libc/src/ctype/islower.h new file mode 100644 index 000000000000..7643542fb7a9 --- /dev/null +++ b/libc/src/ctype/islower.h @@ -0,0 +1,18 @@ +//===-- Implementation header for islower -------------------------*-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 + +namespace __llvm_libc { + +int islower(int c); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_CTYPE_ISLOWER_H diff --git a/libc/src/ctype/isupper.cpp b/libc/src/ctype/isupper.cpp new file mode 100644 index 000000000000..57aed961d1e5 --- /dev/null +++ b/libc/src/ctype/isupper.cpp @@ -0,0 +1,22 @@ +//===-- 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.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(isupper)(int c) { + const unsigned ch = c; + return (ch - 'A') < 26; +} + +} // namespace __llvm_libc diff --git a/libc/src/ctype/isupper.h b/libc/src/ctype/isupper.h new file mode 100644 index 000000000000..7a1f2270943a --- /dev/null +++ b/libc/src/ctype/isupper.h @@ -0,0 +1,18 @@ +//===-- 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_H +#define LLVM_LIBC_SRC_CTYPE_ISUPPER_H + +namespace __llvm_libc { + +int isupper(int c); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_CTYPE_ISUPPER_H diff --git a/libc/test/src/ctype/CMakeLists.txt b/libc/test/src/ctype/CMakeLists.txt index 7834746ab1d7..c9959465c697 100644 --- a/libc/test/src/ctype/CMakeLists.txt +++ b/libc/test/src/ctype/CMakeLists.txt @@ -29,3 +29,23 @@ add_libc_unittest( DEPENDS libc.src.ctype.isdigit ) + +add_libc_unittest( + islower + SUITE + libc_ctype_unittests + SRCS + islower_test.cpp + DEPENDS + libc.src.ctype.islower +) + +add_libc_unittest( + isupper + SUITE + libc_ctype_unittests + SRCS + isupper_test.cpp + DEPENDS + libc.src.ctype.isupper +) diff --git a/libc/test/src/ctype/isalnum_test.cpp b/libc/test/src/ctype/isalnum_test.cpp index 1c4ad7d3ff8a..ca77285c5614 100644 --- a/libc/test/src/ctype/isalnum_test.cpp +++ b/libc/test/src/ctype/isalnum_test.cpp @@ -7,21 +7,17 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isalnum.h" -#include "utils/UnitTest/Test.h" -// Helper function that makes a call to isalnum a bit cleaner -// for use with testing utilities, since it explicitly requires -// a boolean value for EXPECT_TRUE and EXPECT_FALSE. -bool call_isalnum(int c) { return __llvm_libc::isalnum(c); } +#include "utils/UnitTest/Test.h" TEST(IsAlNum, DefaultLocale) { // Loops through all characters, verifying that numbers and letters - // return true and everything else returns false. + // return non-zero integer and everything else returns a zero. for (int c = 0; c < 255; ++c) { if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) - EXPECT_TRUE(call_isalnum(c)); + EXPECT_NE(__llvm_libc::isalnum(c), 0); else - EXPECT_FALSE(call_isalnum(c)); + EXPECT_EQ(__llvm_libc::isalnum(c), 0); } } diff --git a/libc/test/src/ctype/isalpha_test.cpp b/libc/test/src/ctype/isalpha_test.cpp index 81fc7248f871..d91219b50406 100644 --- a/libc/test/src/ctype/isalpha_test.cpp +++ b/libc/test/src/ctype/isalpha_test.cpp @@ -7,20 +7,16 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isalpha.h" + #include "utils/UnitTest/Test.h" -// Helper function that makes a call to isalpha a bit cleaner -// for use with testing utilities, since it explicitly requires -// a boolean value for EXPECT_TRUE and EXPECT_FALSE. -bool call_isalpha(int c) { return __llvm_libc::isalpha(c); } - TEST(IsAlpha, DefaultLocale) { - // Loops through all characters, verifying that letters return true - // and everything else returns false. + // Loops through all characters, verifying that letters return a + // non-zero integer and everything else returns zero. for (int ch = 0; ch < 255; ++ch) { if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) - EXPECT_TRUE(call_isalpha(ch)); + EXPECT_NE(__llvm_libc::isalpha(ch), 0); else - EXPECT_FALSE(call_isalpha(ch)); + EXPECT_EQ(__llvm_libc::isalpha(ch), 0); } } diff --git a/libc/test/src/ctype/isdigit_test.cpp b/libc/test/src/ctype/isdigit_test.cpp index 6fea9564db67..2430a92425c4 100644 --- a/libc/test/src/ctype/isdigit_test.cpp +++ b/libc/test/src/ctype/isdigit_test.cpp @@ -7,20 +7,16 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isdigit.h" + #include "utils/UnitTest/Test.h" -// Helper function that makes a call to isdigit a bit cleaner -// for use with testing utilities, since it explicitly requires -// a boolean value for EXPECT_TRUE and EXPECT_FALSE. -bool call_isdigit(int c) { return __llvm_libc::isdigit(c); } - TEST(IsDigit, DefaultLocale) { - // Loops through all characters, verifying that numbers return true - // and everything else returns false. + // Loops through all characters, verifying that numbers return a + // non-zero integer and everything else returns zero. for (int ch = 0; ch < 255; ++ch) { if ('0' <= ch && ch <= '9') - EXPECT_TRUE(call_isdigit(ch)); + EXPECT_NE(__llvm_libc::isdigit(ch), 0); else - EXPECT_FALSE(call_isdigit(ch)); + EXPECT_EQ(__llvm_libc::isdigit(ch), 0); } } diff --git a/libc/test/src/ctype/islower_test.cpp b/libc/test/src/ctype/islower_test.cpp new file mode 100644 index 000000000000..9b38cabc67aa --- /dev/null +++ b/libc/test/src/ctype/islower_test.cpp @@ -0,0 +1,21 @@ +//===-- Unittests for 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.h" +#include "utils/UnitTest/Test.h" + +TEST(IsLower, DefaultLocale) { + // Loops through all characters, verifying that lowercase letters + // return a non-zero integer and everything else returns zero. + for (int ch = 0; ch < 255; ++ch) { + if ('a' <= ch && ch <= 'z') + EXPECT_NE(__llvm_libc::islower(ch), 0); + else + EXPECT_EQ(__llvm_libc::islower(ch), 0); + } +} diff --git a/libc/test/src/ctype/isupper_test.cpp b/libc/test/src/ctype/isupper_test.cpp new file mode 100644 index 000000000000..0a13f4e11b0e --- /dev/null +++ b/libc/test/src/ctype/isupper_test.cpp @@ -0,0 +1,21 @@ +//===-- Unittests for 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.h" +#include "utils/UnitTest/Test.h" + +TEST(IsUpper, DefaultLocale) { + // Loops through all characters, verifying that uppercase letters + // return a non-zero integer and everything else returns zero. + for (int ch = 0; ch < 255; ++ch) { + if ('A' <= ch && ch <= 'Z') + EXPECT_NE(__llvm_libc::isupper(ch), 0); + else + EXPECT_EQ(__llvm_libc::isupper(ch), 0); + } +}