[libc] Add iswctype and wctype (#191178)

Implement the iswctype and wctype functions from <wctype.h>.

- Add wctype_t type definition.
- Implement wctype to map property strings to classification
descriptors.
- Implement iswctype as a dispatcher over existing wide character
classification functions.
- Add corresponding entrypoints and unit tests.

Refs: https://github.com/llvm/llvm-project/issues/191076

---------

Co-authored-by: Zile Xiong <xiongzile99@gmail.com>
This commit is contained in:
ElioandZile Xiong authored and GitHub committed 2026-04-17 11:52:20 +01:00
1 parent 7f3ed0c45c
commit d00a49fc34
25 files changed
+590 -2

No files matched your search

@@ -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
@@ -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
@@ -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)
@@ -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
+2
View File
@@ -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)
+2
View File
@@ -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
+2
View File
@@ -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
+2
View File
@@ -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
+9
View File
@@ -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
+23
View File
@@ -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
+69
View File
@@ -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 <wctype.h> 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 <wctype.h>.
// 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 <wctype.h>
#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
+1
View File
@@ -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(
@@ -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)
+14
View File
@@ -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
+14
View File
@@ -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*
+82 -1
View File
@@ -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<wctype_mapping, 12> 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);
+21
View File
@@ -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
)
+22
View File
@@ -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<wchar_t>(c), desc);
}
} // namespace LIBC_NAMESPACE_DECL
+22
View File
@@ -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
+21
View File
@@ -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
+22
View File
@@ -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
+16 -1
View File
@@ -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
+21
View File
@@ -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
)
+181
View File
@@ -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<wctype_t>(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<wctype_t>(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<wctype_t>(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<wctype_t>(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<wctype_t>(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<wctype_t>(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<wctype_t>(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<wctype_t>(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<wctype_t>(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<wctype_t>(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<wctype_t>(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<wctype_t>(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);
}
+35
View File
@@ -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<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("alpha"), static_cast<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("blank"), static_cast<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("cntrl"), static_cast<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("digit"), static_cast<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("graph"), static_cast<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("lower"), static_cast<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("print"), static_cast<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("punct"), static_cast<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("space"), static_cast<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("upper"), static_cast<wctype_t>(0));
EXPECT_NE(LIBC_NAMESPACE::wctype("xdigit"), static_cast<wctype_t>(0));
}
TEST(LlvmLibcwctype, InvalidPropertiesReturnZero) {
EXPECT_EQ(LIBC_NAMESPACE::wctype(nullptr), static_cast<wctype_t>(0));
EXPECT_EQ(LIBC_NAMESPACE::wctype(""), static_cast<wctype_t>(0));
EXPECT_EQ(LIBC_NAMESPACE::wctype("foo"), static_cast<wctype_t>(0));
EXPECT_EQ(LIBC_NAMESPACE::wctype("Alpha"), static_cast<wctype_t>(0));
EXPECT_EQ(LIBC_NAMESPACE::wctype("xdigit "), static_cast<wctype_t>(0));
EXPECT_EQ(LIBC_NAMESPACE::wctype(" alnum"), static_cast<wctype_t>(0));
}