diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt index 9c0e71b2beec..41c80efc6422 100644 --- a/libc/config/baremetal/arm/entrypoints.txt +++ b/libc/config/baremetal/arm/entrypoints.txt @@ -314,6 +314,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wctype.iswxdigit libc.src.wctype.iswpunct libc.src.wctype.iswprint + libc.src.wctype.iswctype + libc.src.wctype.wctype # internal entrypoints libc.startup.baremetal.init libc.startup.baremetal.fini diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt index 5c88bc4ae1fb..88eacfae1296 100644 --- a/libc/config/baremetal/riscv/entrypoints.txt +++ b/libc/config/baremetal/riscv/entrypoints.txt @@ -311,6 +311,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wctype.iswxdigit libc.src.wctype.iswpunct libc.src.wctype.iswprint + libc.src.wctype.iswctype + libc.src.wctype.wctype # internal entrypoints libc.startup.baremetal.init diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt index c93ba47a6f2d..914d2b7918da 100644 --- a/libc/config/darwin/aarch64/entrypoints.txt +++ b/libc/config/darwin/aarch64/entrypoints.txt @@ -114,6 +114,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wctype.iswxdigit libc.src.wctype.iswpunct libc.src.wctype.iswprint + libc.src.wctype.iswctype + libc.src.wctype.wctype ) if(LLVM_LIBC_FULL_BUILD) diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 6f7567cf3789..87bd5461496b 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -386,6 +386,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wctype.iswxdigit libc.src.wctype.iswpunct libc.src.wctype.iswprint + libc.src.wctype.iswctype + libc.src.wctype.wctype # sys/uio.h entrypoints libc.src.sys.uio.writev diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt index 167d762f36cb..8a4d88b5ba98 100644 --- a/libc/config/linux/arm/entrypoints.txt +++ b/libc/config/linux/arm/entrypoints.txt @@ -206,6 +206,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wctype.iswxdigit libc.src.wctype.iswpunct libc.src.wctype.iswprint + libc.src.wctype.iswctype + libc.src.wctype.wctype ) if(LLVM_LIBC_FULL_BUILD) diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 1856d8edba7d..ea117c1d83c2 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -390,6 +390,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wctype.iswxdigit libc.src.wctype.iswpunct libc.src.wctype.iswprint + libc.src.wctype.iswctype + libc.src.wctype.wctype # sys/uio.h entrypoints libc.src.sys.uio.writev diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index fe5991c695e2..5c69c8808b2c 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -440,6 +440,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wctype.iswxdigit libc.src.wctype.iswpunct libc.src.wctype.iswprint + libc.src.wctype.iswctype + libc.src.wctype.wctype # sys/uio.h entrypoints libc.src.sys.uio.writev diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt index c6db359933f0..94d1d00e676d 100644 --- a/libc/config/windows/entrypoints.txt +++ b/libc/config/windows/entrypoints.txt @@ -120,6 +120,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wctype.iswxdigit libc.src.wctype.iswpunct libc.src.wctype.iswprint + libc.src.wctype.iswctype + libc.src.wctype.wctype ) set(TARGET_LIBM_ENTRYPOINTS diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt index 7e1a8974fa48..7395f70c0d2a 100644 --- a/libc/hdr/types/CMakeLists.txt +++ b/libc/hdr/types/CMakeLists.txt @@ -443,6 +443,15 @@ add_proxy_header_library( libc.include.wchar ) + +add_proxy_header_library( + wctype_t + HDRS + wctype_t.h + FULL_BUILD_DEPENDS + libc.include.llvm-libc-types.wctype_t +) + add_proxy_header_library( uid_t HDRS diff --git a/libc/hdr/types/wctype_t.h b/libc/hdr/types/wctype_t.h new file mode 100644 index 000000000000..39f33b87f3e1 --- /dev/null +++ b/libc/hdr/types/wctype_t.h @@ -0,0 +1,23 @@ +//===-- Definition of wctype_t.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_HDR_TYPES_WCTYPE_T_H +#define LLVM_LIBC_HDR_TYPES_WCTYPE_T_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-types/wctype_t.h" + +#else // overlay mode + +#include "hdr/wctype_overlay.h" + +#endif // LLVM_LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_TYPES_WCTYPE_T_H diff --git a/libc/hdr/wctype_overlay.h b/libc/hdr/wctype_overlay.h new file mode 100644 index 000000000000..3ae7fbe24ec8 --- /dev/null +++ b/libc/hdr/wctype_overlay.h @@ -0,0 +1,69 @@ +//===-- Including wctype.h in overlay mode --------------------------------===// +// +// 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_HDR_WCTYPE_OVERLAY_H +#define LLVM_LIBC_HDR_WCTYPE_OVERLAY_H + +#ifdef LIBC_FULL_BUILD +#error "This header should only be included in overlay mode" +#endif + +// Overlay mode + +// glibc header might provide extern inline definitions for few +// functions, causing external alias errors. They are guarded by +// `__USE_EXTERN_INLINES` macro. We temporarily disable `__USE_EXTERN_INLINES` +// macro by defining `__NO_INLINE__` before including . +// And the same with `__USE_FORTIFY_LEVEL`, which will be temporarily disabled +// with `_FORTIFY_SOURCE`. + +#ifdef _FORTIFY_SOURCE +#define LIBC_OLD_FORTIFY_SOURCE _FORTIFY_SOURCE +#undef _FORTIFY_SOURCE +#endif + +#ifndef __NO_INLINE__ +#define __NO_INLINE__ 1 +#define LIBC_SET_NO_INLINE +#endif + +#ifdef __USE_EXTERN_INLINES +#define LIBC_OLD_USE_EXTERN_INLINES +#undef __USE_EXTERN_INLINES +#endif + +#ifdef __USE_FORTIFY_LEVEL +#define LIBC_OLD_USE_FORTIFY_LEVEL __USE_FORTIFY_LEVEL +#undef __USE_FORTIFY_LEVEL +#define __USE_FORTIFY_LEVEL 0 +#endif + +#include + +#ifdef LIBC_OLD_FORTIFY_SOURCE +#define _FORTIFY_SOURCE LIBC_OLD_FORTIFY_SOURCE +#undef LIBC_OLD_FORTIFY_SOURCE +#endif + +#ifdef LIBC_SET_NO_INLINE +#undef __NO_INLINE__ +#undef LIBC_SET_NO_INLINE +#endif + +#ifdef LIBC_OLD_USE_FORTIFY_LEVEL +#undef __USE_FORTIFY_LEVEL +#define __USE_FORTIFY_LEVEL LIBC_OLD_USE_FORTIFY_LEVEL +#undef LIBC_OLD_USE_FORTIFY_LEVEL +#endif + +#ifdef LIBC_OLD_USE_EXTERN_INLINES +#define __USE_EXTERN_INLINES +#undef LIBC_OLD_USE_EXTERN_INLINES +#endif + +#endif // LLVM_LIBC_HDR_WCTYPE_OVERLAY_H diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index ab1d4967d418..74d31025f9f4 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -887,6 +887,7 @@ add_header_macro( DEPENDS .llvm_libc_common_h .llvm-libc-types.wint_t + .llvm-libc-types.wctype_t ) add_header_macro( diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index e40f6e194ab3..021e0a29555c 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -191,6 +191,7 @@ add_header( libc.include.llvm-libc-macros.stdint_macros ) add_header(wint_t HDR wint_t.h) +add_header(wctype_t HDR wctype_t.h) add_header(sa_family_t HDR sa_family_t.h) add_header(socklen_t HDR socklen_t.h) add_header(struct_sockaddr_un HDR struct_sockaddr_un.h DEPENDS .sa_family_t) diff --git a/libc/include/llvm-libc-types/wctype_t.h b/libc/include/llvm-libc-types/wctype_t.h new file mode 100644 index 000000000000..47840df02fc4 --- /dev/null +++ b/libc/include/llvm-libc-types/wctype_t.h @@ -0,0 +1,14 @@ +//===-- Definition of wctype_t types --------------------------------------===// +// +// 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_WCTYPE_T_H +#define LLVM_LIBC_TYPES_WCTYPE_T_H + +typedef unsigned int wctype_t; + +#endif // LLVM_LIBC_TYPES_WCTYPE_T_H diff --git a/libc/include/wctype.yaml b/libc/include/wctype.yaml index 932ff6ac1b13..a5163ecc2d3f 100644 --- a/libc/include/wctype.yaml +++ b/libc/include/wctype.yaml @@ -1,6 +1,7 @@ header: wctype.h types: - type_name: wint_t + - type_name: wctype_t functions: - name: iswalpha standards: @@ -74,3 +75,16 @@ functions: return_type: int arguments: - type: wint_t + - name: iswctype + standards: + - stdc + return_type: int + arguments: + - type: wint_t + - type: wctype_t + - name: wctype + standards: + - stdc + return_type: wctype_t + arguments: + - type: const char* diff --git a/libc/src/__support/wctype_utils.h b/libc/src/__support/wctype_utils.h index a80c78d54c79..9c66990f8b9d 100644 --- a/libc/src/__support/wctype_utils.h +++ b/libc/src/__support/wctype_utils.h @@ -10,6 +10,9 @@ #define LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H #include "hdr/types/wchar_t.h" +#include "hdr/types/wctype_t.h" +#include "src/__support/CPP/array.h" +#include "src/__support/CPP/string_view.h" #include "src/__support/macros/attributes.h" // LIBC_INLINE #include "src/__support/macros/config.h" @@ -551,7 +554,6 @@ LIBC_INLINE constexpr bool isprint(wchar_t wch) { return lookup_properties(wch) & PropertyFlag::PRINT; #endif } - LIBC_INLINE constexpr bool isxdigit(wchar_t wch) { // Hexadecimal digits are the same in C.UTF8 as in ASCII return ascii::isxdigit(wch); @@ -579,6 +581,85 @@ LIBC_INLINE constexpr bool ispunct(wchar_t wch) { #endif } +struct wctype_mapping { + cpp::string_view name; + wctype_t desc; +}; + +LIBC_INLINE constexpr wctype_t WCTYPE_INVALID = 0; +LIBC_INLINE constexpr wctype_t WCTYPE_ALNUM = 1; +LIBC_INLINE constexpr wctype_t WCTYPE_ALPHA = 2; +LIBC_INLINE constexpr wctype_t WCTYPE_BLANK = 3; +LIBC_INLINE constexpr wctype_t WCTYPE_CNTRL = 4; +LIBC_INLINE constexpr wctype_t WCTYPE_DIGIT = 5; +LIBC_INLINE constexpr wctype_t WCTYPE_GRAPH = 6; +LIBC_INLINE constexpr wctype_t WCTYPE_LOWER = 7; +LIBC_INLINE constexpr wctype_t WCTYPE_PRINT = 8; +LIBC_INLINE constexpr wctype_t WCTYPE_PUNCT = 9; +LIBC_INLINE constexpr wctype_t WCTYPE_SPACE = 10; +LIBC_INLINE constexpr wctype_t WCTYPE_UPPER = 11; +LIBC_INLINE constexpr wctype_t WCTYPE_XDIGIT = 12; + +LIBC_INLINE constexpr cpp::array mappings = {{ + {"alnum", WCTYPE_ALNUM}, + {"alpha", WCTYPE_ALPHA}, + {"blank", WCTYPE_BLANK}, + {"cntrl", WCTYPE_CNTRL}, + {"digit", WCTYPE_DIGIT}, + {"graph", WCTYPE_GRAPH}, + {"lower", WCTYPE_LOWER}, + {"print", WCTYPE_PRINT}, + {"punct", WCTYPE_PUNCT}, + {"space", WCTYPE_SPACE}, + {"upper", WCTYPE_UPPER}, + {"xdigit", WCTYPE_XDIGIT}, +}}; + +LIBC_INLINE constexpr wctype_t wctype(const char *property) { + if (!property) + return WCTYPE_INVALID; + + cpp::string_view prop(property); + + for (const auto &wc : mappings) { + if (wc.name == prop) { + return wc.desc; + } + } + return WCTYPE_INVALID; +} + +LIBC_INLINE constexpr int iswctype(wchar_t c, wctype_t desc) { + switch (desc) { + case WCTYPE_ALNUM: + return isalnum(c); + case WCTYPE_ALPHA: + return isalpha(c); + case WCTYPE_BLANK: + return isblank(c); + case WCTYPE_CNTRL: + return iscntrl(c); + case WCTYPE_DIGIT: + return isdigit(c); + case WCTYPE_GRAPH: + return isgraph(c); + case WCTYPE_LOWER: + return islower(c); + case WCTYPE_PRINT: + return isprint(c); + case WCTYPE_PUNCT: + return ispunct(c); + case WCTYPE_SPACE: + return isspace(c); + case WCTYPE_UPPER: + return isupper(c); + case WCTYPE_XDIGIT: + return isxdigit(c); + default: + return 0; + } +} + LIBC_INLINE constexpr wchar_t tolower(wchar_t wch) { #if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8 return ascii::tolower(wch); diff --git a/libc/src/wctype/CMakeLists.txt b/libc/src/wctype/CMakeLists.txt index 07bfed39980c..57f9e7753a9f 100644 --- a/libc/src/wctype/CMakeLists.txt +++ b/libc/src/wctype/CMakeLists.txt @@ -130,3 +130,24 @@ add_entrypoint_object( libc.src.__support.wctype_utils libc.hdr.types.wint_t ) + +add_entrypoint_object( + iswctype + SRCS + iswctype.cpp + HDRS + iswctype.h + DEPENDS + libc.src.__support.wctype_utils + libc.hdr.types.wint_t +) + +add_entrypoint_object( + wctype + SRCS + wctype.cpp + HDRS + wctype.h + DEPENDS + libc.src.__support.wctype_utils +) diff --git a/libc/src/wctype/iswctype.cpp b/libc/src/wctype/iswctype.cpp new file mode 100644 index 000000000000..1604836225fe --- /dev/null +++ b/libc/src/wctype/iswctype.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of iswctype ----------------------------------------===// +// +// 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/iswctype.h" +#include "src/__support/common.h" +#include "src/__support/wctype_utils.h" + +#include "hdr/types/wctype_t.h" +#include "hdr/types/wint_t.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, iswctype, (wint_t c, wctype_t desc)) { + return internal::iswctype(static_cast(c), desc); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wctype/iswctype.h b/libc/src/wctype/iswctype.h new file mode 100644 index 000000000000..10a0f3e969c8 --- /dev/null +++ b/libc/src/wctype/iswctype.h @@ -0,0 +1,22 @@ +//===-- Implementation header for iswctype ----------------------*- 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_ISWCTYPE_H +#define LLVM_LIBC_SRC_WCTYPE_ISWCTYPE_H + +#include "hdr/types/wctype_t.h" +#include "hdr/types/wint_t.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE_DECL { + +int iswctype(wint_t c, wctype_t desc); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCTYPE_ISWCTYPE_H diff --git a/libc/src/wctype/wctype.cpp b/libc/src/wctype/wctype.cpp new file mode 100644 index 000000000000..59c28dcf5a43 --- /dev/null +++ b/libc/src/wctype/wctype.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of wctype ----------------------------------------===// +// +// 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/wctype.h" +#include "src/__support/common.h" +#include "src/__support/wctype_utils.h" + +#include "hdr/types/wctype_t.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(wctype_t, wctype, (const char *property)) { + return internal::wctype(property); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wctype/wctype.h b/libc/src/wctype/wctype.h new file mode 100644 index 000000000000..98300e49f7e0 --- /dev/null +++ b/libc/src/wctype/wctype.h @@ -0,0 +1,22 @@ +//===-- Implementation header for iswctype ----------------------*- 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_WCTYPE_H +#define LLVM_LIBC_SRC_WCTYPE_WCTYPE_H + +#include "hdr/types/wctype_t.h" +#include "hdr/types/wint_t.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE_DECL { + +wctype_t wctype(const char *property); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCTYPE_WCTYPE_H diff --git a/libc/test/src/__support/wctype_utils_test.cpp b/libc/test/src/__support/wctype_utils_test.cpp index 9bc7e818cdbc..88cd56cc0cae 100644 --- a/libc/test/src/__support/wctype_utils_test.cpp +++ b/libc/test/src/__support/wctype_utils_test.cpp @@ -1,7 +1,15 @@ +//===-- Unittests for wctype utils ----------------------------------------===// +// +// 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 "hdr/types/wctype_t.h" #include "src/__support/macros/config.h" #include "src/__support/wctype/wctype_classification_utils.h" #include "test/UnitTest/Test.h" - namespace { namespace ascii_mode { @@ -9,7 +17,12 @@ namespace ascii_mode { #define LIBC_CONF_WCTYPE_MODE LIBC_WCTYPE_MODE_ASCII #undef LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H + +namespace LIBC_NAMESPACE_DECL { +namespace cpp = ::LIBC_NAMESPACE::cpp; +} // namespace LIBC_NAMESPACE_DECL #include "src/__support/wctype_utils.h" + } // namespace ascii_mode namespace utf8_mode { @@ -19,9 +32,11 @@ namespace utf8_mode { namespace LIBC_NAMESPACE_DECL { using ::LIBC_NAMESPACE::lookup_properties; using ::LIBC_NAMESPACE::PropertyFlag; +namespace cpp = ::LIBC_NAMESPACE::cpp; } // namespace LIBC_NAMESPACE_DECL #undef LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H + #include "src/__support/wctype_utils.h" } // namespace utf8_mode diff --git a/libc/test/src/wctype/CMakeLists.txt b/libc/test/src/wctype/CMakeLists.txt index a5f85856dfb3..f7cdcc77482e 100644 --- a/libc/test/src/wctype/CMakeLists.txt +++ b/libc/test/src/wctype/CMakeLists.txt @@ -121,3 +121,24 @@ add_libc_test( DEPENDS libc.src.wctype.iswprint ) + +add_libc_test( + iswctype_test + SUITE + libc_wctype_unittests + SRCS + iswctype_test.cpp + DEPENDS + libc.src.wctype.iswctype + libc.src.wctype.wctype +) + +add_libc_test( + wctype_test + SUITE + libc_wctype_unittests + SRCS + wctype_test.cpp + DEPENDS + libc.src.wctype.wctype +) diff --git a/libc/test/src/wctype/iswctype_test.cpp b/libc/test/src/wctype/iswctype_test.cpp new file mode 100644 index 000000000000..4aed4d047b61 --- /dev/null +++ b/libc/test/src/wctype/iswctype_test.cpp @@ -0,0 +1,181 @@ +//===-- Unittests for iswctype --------------------------------------------===// +// +// 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/iswctype.h" +#include "src/wctype/wctype.h" + +#include "test/UnitTest/Test.h" + +TEST(LlvmLibciswctype, Alnum) { + const wctype_t desc = LIBC_NAMESPACE::wctype("alnum"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'a', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'Z', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'5', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'!', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L' ', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'\n', desc), 0); +} + +TEST(LlvmLibciswctype, Alpha) { + const wctype_t desc = LIBC_NAMESPACE::wctype("alpha"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'a', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'Z', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'1', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L' ', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'_', desc), 0); +} + +TEST(LlvmLibciswctype, Blank) { + const wctype_t desc = LIBC_NAMESPACE::wctype("blank"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L' ', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'\t', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'\n', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'\r', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'A', desc), 0); +} + +TEST(LlvmLibciswctype, Cntrl) { + const wctype_t desc = LIBC_NAMESPACE::wctype("cntrl"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'\0', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'\t', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'\n', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'\r', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(0x1f, desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(0x7f, desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'A', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L' ', desc), 0); +} + +TEST(LlvmLibciswctype, Digit) { + const wctype_t desc = LIBC_NAMESPACE::wctype("digit"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'0', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'9', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'a', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L' ', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'/', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L':', desc), 0); +} + +TEST(LlvmLibciswctype, Graph) { + const wctype_t desc = LIBC_NAMESPACE::wctype("graph"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'A', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'1', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'!', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'~', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L' ', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'\n', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'\t', desc), 0); +} + +TEST(LlvmLibciswctype, Lower) { + const wctype_t desc = LIBC_NAMESPACE::wctype("lower"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'a', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'z', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'A', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'1', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'_', desc), 0); +} + +TEST(LlvmLibciswctype, Print) { + const wctype_t desc = LIBC_NAMESPACE::wctype("print"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L' ', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'A', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'0', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'~', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'\n', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'\t', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'\0', desc), 0); +} + +TEST(LlvmLibciswctype, Punct) { + const wctype_t desc = LIBC_NAMESPACE::wctype("punct"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'!', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'?', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'_', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'[', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'a', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'1', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L' ', desc), 0); +} + +TEST(LlvmLibciswctype, Space) { + const wctype_t desc = LIBC_NAMESPACE::wctype("space"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L' ', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'\t', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'\n', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'\v', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'\f', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'\r', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'A', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'1', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'!', desc), 0); +} + +TEST(LlvmLibciswctype, Upper) { + const wctype_t desc = LIBC_NAMESPACE::wctype("upper"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'A', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'Z', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'a', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'1', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'_', desc), 0); +} + +TEST(LlvmLibciswctype, XDigit) { + const wctype_t desc = LIBC_NAMESPACE::wctype("xdigit"); + ASSERT_NE(desc, static_cast(0)); + + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'0', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'9', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'a', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'f', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'A', desc), 0); + EXPECT_NE(LIBC_NAMESPACE::iswctype(L'F', desc), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'g', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'G', desc), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'?', desc), 0); +} + +TEST(LlvmLibciswctype, InvalidDescriptor) { + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'a', 0), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L'0', 0), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswctype(L' ', 0), 0); +} diff --git a/libc/test/src/wctype/wctype_test.cpp b/libc/test/src/wctype/wctype_test.cpp new file mode 100644 index 000000000000..e4aa1bb6694d --- /dev/null +++ b/libc/test/src/wctype/wctype_test.cpp @@ -0,0 +1,35 @@ +//===-- Unittests for wctype ----------------------------------------------===// +// +// 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/wctype.h" + +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcwctype, ValidPropertiesReturnNonZero) { + EXPECT_NE(LIBC_NAMESPACE::wctype("alnum"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("alpha"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("blank"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("cntrl"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("digit"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("graph"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("lower"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("print"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("punct"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("space"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("upper"), static_cast(0)); + EXPECT_NE(LIBC_NAMESPACE::wctype("xdigit"), static_cast(0)); +} + +TEST(LlvmLibcwctype, InvalidPropertiesReturnZero) { + EXPECT_EQ(LIBC_NAMESPACE::wctype(nullptr), static_cast(0)); + EXPECT_EQ(LIBC_NAMESPACE::wctype(""), static_cast(0)); + EXPECT_EQ(LIBC_NAMESPACE::wctype("foo"), static_cast(0)); + EXPECT_EQ(LIBC_NAMESPACE::wctype("Alpha"), static_cast(0)); + EXPECT_EQ(LIBC_NAMESPACE::wctype("xdigit "), static_cast(0)); + EXPECT_EQ(LIBC_NAMESPACE::wctype(" alnum"), static_cast(0)); +}