diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt index de7549c57ff44..80cd15eebc91f 100644 --- a/libc/config/baremetal/arm/entrypoints.txt +++ b/libc/config/baremetal/arm/entrypoints.txt @@ -278,6 +278,9 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wchar.wcslen libc.src.wchar.wctob + # wctype.h entrypoints + libc.src.wctype.iswalpha + # internal entrypoints libc.startup.baremetal.init libc.startup.baremetal.fini diff --git a/libc/config/baremetal/arm/headers.txt b/libc/config/baremetal/arm/headers.txt index 5666ef7e0012d..1f64afebdaaa7 100644 --- a/libc/config/baremetal/arm/headers.txt +++ b/libc/config/baremetal/arm/headers.txt @@ -23,4 +23,5 @@ set(TARGET_PUBLIC_HEADERS libc.include.time libc.include.uchar libc.include.wchar + libc.include.wctype ) diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt index 7e8c186d52469..c9f8118f6e800 100644 --- a/libc/config/baremetal/riscv/entrypoints.txt +++ b/libc/config/baremetal/riscv/entrypoints.txt @@ -278,6 +278,9 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wchar.wcslen libc.src.wchar.wctob + # wctype.h entrypoints + libc.src.wctype.iswalpha + # internal entrypoints libc.startup.baremetal.init libc.startup.baremetal.fini diff --git a/libc/config/baremetal/riscv/headers.txt b/libc/config/baremetal/riscv/headers.txt index 5666ef7e0012d..1f64afebdaaa7 100644 --- a/libc/config/baremetal/riscv/headers.txt +++ b/libc/config/baremetal/riscv/headers.txt @@ -23,4 +23,5 @@ set(TARGET_PUBLIC_HEADERS libc.include.time libc.include.uchar libc.include.wchar + libc.include.wctype ) diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt index 4674a9309115b..3bfdcdbee555e 100644 --- a/libc/config/darwin/aarch64/entrypoints.txt +++ b/libc/config/darwin/aarch64/entrypoints.txt @@ -99,6 +99,9 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdlib.calloc libc.src.stdlib.realloc libc.src.stdlib.free + + # wctype.h entrypoints + libc.src.wctype.iswalpha ) if(LLVM_LIBC_FULL_BUILD) diff --git a/libc/config/darwin/aarch64/headers.txt b/libc/config/darwin/aarch64/headers.txt index 8f3d6029c9b6a..55a112c0c3ad3 100644 --- a/libc/config/darwin/aarch64/headers.txt +++ b/libc/config/darwin/aarch64/headers.txt @@ -11,4 +11,5 @@ set(TARGET_PUBLIC_HEADERS libc.include.stdlib libc.include.string libc.include.strings + libc.include.wctype ) diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index cff5b7f8312d6..b2abebee017d8 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -363,6 +363,9 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wchar.wcslen libc.src.wchar.wctob + # wctype.h entrypoints + libc.src.wctype.iswalpha + # sys/uio.h entrypoints libc.src.sys.uio.writev libc.src.sys.uio.readv diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt index 01b0bf36498ce..6d3bc9188583b 100644 --- a/libc/config/linux/aarch64/headers.txt +++ b/libc/config/linux/aarch64/headers.txt @@ -57,4 +57,5 @@ set(TARGET_PUBLIC_HEADERS libc.include.uchar libc.include.unistd libc.include.wchar + libc.include.wctype ) diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt index a1203cc4991af..5865dc93a9aef 100644 --- a/libc/config/linux/arm/entrypoints.txt +++ b/libc/config/linux/arm/entrypoints.txt @@ -191,6 +191,9 @@ set(TARGET_LIBC_ENTRYPOINTS # sys/time.h entrypoints libc.src.sys.time.setitimer libc.src.sys.time.getitimer + + # wctype.h entrypoints + libc.src.wctype.iswalpha ) if(LLVM_LIBC_FULL_BUILD) diff --git a/libc/config/linux/arm/headers.txt b/libc/config/linux/arm/headers.txt index 9aabac5dea33c..14c730e2b77b1 100644 --- a/libc/config/linux/arm/headers.txt +++ b/libc/config/linux/arm/headers.txt @@ -17,6 +17,7 @@ set(TARGET_PUBLIC_HEADERS libc.include.strings libc.include.uchar libc.include.wchar + libc.include.wctype # Disabled due to epoll_wait syscalls not being available on this platform. # libc.include.sys_epoll diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 14361f5b6beff..79077a5e66ef5 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -368,6 +368,9 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wchar.wcslen libc.src.wchar.wctob + # wctype.h entrypoints + libc.src.wctype.iswalpha + # sys/uio.h entrypoints libc.src.sys.uio.writev libc.src.sys.uio.readv diff --git a/libc/config/linux/riscv/headers.txt b/libc/config/linux/riscv/headers.txt index 01b0bf36498ce..6d3bc9188583b 100644 --- a/libc/config/linux/riscv/headers.txt +++ b/libc/config/linux/riscv/headers.txt @@ -57,4 +57,5 @@ set(TARGET_PUBLIC_HEADERS libc.include.uchar libc.include.unistd libc.include.wchar + libc.include.wctype ) diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 9223911f04a93..381359cec6f1d 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -396,6 +396,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wchar.wcstoul libc.src.wchar.wcstoull + # wctype.h entrypoints + libc.src.wctype.iswalpha # sys/uio.h entrypoints libc.src.sys.uio.writev diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt index 01b0bf36498ce..6d3bc9188583b 100644 --- a/libc/config/linux/x86_64/headers.txt +++ b/libc/config/linux/x86_64/headers.txt @@ -57,4 +57,5 @@ set(TARGET_PUBLIC_HEADERS libc.include.uchar libc.include.unistd libc.include.wchar + libc.include.wctype ) diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt index 8898fd74c302f..18027298acc18 100644 --- a/libc/config/windows/entrypoints.txt +++ b/libc/config/windows/entrypoints.txt @@ -105,6 +105,9 @@ set(TARGET_LIBC_ENTRYPOINTS # unistd.h entrypoints libc.src.unistd.getentropy + + # wctype.h entrypoints + libc.src.wctype.iswalpha ) set(TARGET_LIBM_ENTRYPOINTS diff --git a/libc/config/windows/headers.txt b/libc/config/windows/headers.txt index 6d9aae9276924..d4a0947d867bb 100644 --- a/libc/config/windows/headers.txt +++ b/libc/config/windows/headers.txt @@ -7,4 +7,5 @@ set(TARGET_PUBLIC_HEADERS libc.include.fenv libc.include.math libc.include.unistd + libc.include.wctype ) diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index 55268d19529c7..984b960acb2d7 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -720,6 +720,15 @@ add_header_macro( .llvm-libc-types.wchar_t ) +add_header_macro( + wctype + ../libc/include/wctype.yaml + wctype.h + DEPENDS + .llvm_libc_common_h + .llvm-libc-types.wint_t +) + add_header_macro( locale ../libc/include/locale.yaml diff --git a/libc/include/wctype.yaml b/libc/include/wctype.yaml new file mode 100644 index 0000000000000..fb4f96f7d17e4 --- /dev/null +++ b/libc/include/wctype.yaml @@ -0,0 +1,10 @@ +header: wctype.h +types: + - type_name: wint_t +functions: + - name: iswalpha + standards: + - stdc + return_type: int + arguments: + - type: wint_t diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt index a665253c4cc03..d7a1e1f49e6ff 100644 --- a/libc/src/CMakeLists.txt +++ b/libc/src/CMakeLists.txt @@ -17,6 +17,7 @@ add_subdirectory(strings) add_subdirectory(time) add_subdirectory(unistd) add_subdirectory(wchar) +add_subdirectory(wctype) if(${LIBC_TARGET_OS} STREQUAL "linux") add_subdirectory(dirent) diff --git a/libc/src/wctype/CMakeLists.txt b/libc/src/wctype/CMakeLists.txt new file mode 100644 index 0000000000000..3ac5eaef8ed8b --- /dev/null +++ b/libc/src/wctype/CMakeLists.txt @@ -0,0 +1,9 @@ +add_entrypoint_object( + iswalpha + SRCS + iswalpha.cpp + HDRS + iswalpha.h + DEPENDS + libc.src.__support.wctype_utils +) diff --git a/libc/src/wctype/iswalpha.cpp b/libc/src/wctype/iswalpha.cpp new file mode 100644 index 0000000000000..e18f29370fbd0 --- /dev/null +++ b/libc/src/wctype/iswalpha.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of iswalpha ----------------------------------------===// +// +// 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/wctype/iswalpha.h" +#include "src/__support/common.h" +#include "src/__support/wctype_utils.h" + +#include "hdr/types/wint_t.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bool, iswalpha, (wint_t c)) { return internal::iswalpha(c); } + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wctype/iswalpha.h b/libc/src/wctype/iswalpha.h new file mode 100644 index 0000000000000..681fc6ba79a54 --- /dev/null +++ b/libc/src/wctype/iswalpha.h @@ -0,0 +1,21 @@ +//===-- Implementation header for iswalpha ----------------------*- 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_WCTYPE_ISWALPHA_H +#define LLVM_LIBC_SRC_WCTYPE_ISWALPHA_H + +#include "hdr/types/wint_t.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE_DECL { + +bool iswalpha(wint_t c); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCTYPE_ISWALPHA_H diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt index 6dca47b5343e6..b3eba43582074 100644 --- a/libc/test/src/CMakeLists.txt +++ b/libc/test/src/CMakeLists.txt @@ -70,6 +70,7 @@ add_subdirectory(stdlib) add_subdirectory(string) add_subdirectory(strings) add_subdirectory(wchar) +add_subdirectory(wctype) add_subdirectory(time) add_subdirectory(unistd) diff --git a/libc/test/src/wctype/CMakeLists.txt b/libc/test/src/wctype/CMakeLists.txt new file mode 100644 index 0000000000000..5459cdb4a9b71 --- /dev/null +++ b/libc/test/src/wctype/CMakeLists.txt @@ -0,0 +1,11 @@ +add_custom_target(libc_wctype_unittests) + +add_libc_test( + iswalpha_test + SUITE + libc_wctype_unittests + SRCS + iswalpha_test.cpp + DEPENDS + libc.src.wctype.iswalpha +) diff --git a/libc/test/src/wctype/iswalpha_test.cpp b/libc/test/src/wctype/iswalpha_test.cpp new file mode 100644 index 0000000000000..f3f75f4dc7aa5 --- /dev/null +++ b/libc/test/src/wctype/iswalpha_test.cpp @@ -0,0 +1,54 @@ +//===-- Unittests for iswalpha --------------------------------------------===// +// +// 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/__support/CPP/span.h" +#include "src/wctype/iswalpha.h" + +#include "test/UnitTest/LibcTest.h" +#include "test/UnitTest/Test.h" + +namespace { + +// TODO: Merge the wctype tests using this framework. +constexpr char WALPHA_ARRAY[] = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', +}; + +bool in_span(int ch, LIBC_NAMESPACE::cpp::span arr) { + for (size_t i = 0; i < arr.size(); ++i) + if (static_cast(arr[i]) == ch) + return true; + return false; +} + +} // namespace + +TEST(LlvmLibciswalpha, SimpleTest) { + EXPECT_TRUE(LIBC_NAMESPACE::iswalpha('a')); + EXPECT_TRUE(LIBC_NAMESPACE::iswalpha('B')); + + EXPECT_FALSE(LIBC_NAMESPACE::iswalpha('3')); + EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(' ')); + EXPECT_FALSE(LIBC_NAMESPACE::iswalpha('?')); + EXPECT_FALSE(LIBC_NAMESPACE::iswalpha('\0')); + EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(-1)); +} + +TEST(LlvmLibciswalpha, DefaultLocale) { + // Loops through all characters, verifying that letters return + // true and everything else returns false. + for (int ch = -255; ch < 255; ++ch) { + if (in_span(ch, WALPHA_ARRAY)) + EXPECT_TRUE(LIBC_NAMESPACE::iswalpha(ch)); + else + EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(ch)); + } +}