[libc] Implement towupper and towlower entrypoints (#198659)
Following up on #187670 to add public entrypoints for the wctype conversion functions. Assisted-by: Automated tooling, human reviewed. --------- Co-authored-by: Muhammad Bassiouni <60100307+bassiounix@users.noreply.github.com>
This commit is contained in:
parent
218a21cee5
commit
f1c26bce3f
21 changed files with 468 additions and 9 deletions
|
|
@ -417,6 +417,8 @@ set(TARGET_LIBC_ENTRYPOINTS
|
|||
libc.src.wctype.iswprint
|
||||
libc.src.wctype.iswctype
|
||||
libc.src.wctype.wctype
|
||||
libc.src.wctype.towlower
|
||||
libc.src.wctype.towupper
|
||||
|
||||
# sys/uio.h entrypoints
|
||||
libc.src.sys.uio.writev
|
||||
|
|
|
|||
|
|
@ -421,6 +421,8 @@ set(TARGET_LIBC_ENTRYPOINTS
|
|||
libc.src.wctype.iswprint
|
||||
libc.src.wctype.iswctype
|
||||
libc.src.wctype.wctype
|
||||
libc.src.wctype.towlower
|
||||
libc.src.wctype.towupper
|
||||
|
||||
# sys/uio.h entrypoints
|
||||
libc.src.sys.uio.writev
|
||||
|
|
|
|||
|
|
@ -481,6 +481,8 @@ set(TARGET_LIBC_ENTRYPOINTS
|
|||
libc.src.wctype.iswprint
|
||||
libc.src.wctype.iswctype
|
||||
libc.src.wctype.wctype
|
||||
libc.src.wctype.towlower
|
||||
libc.src.wctype.towupper
|
||||
|
||||
# sys/uio.h entrypoints
|
||||
libc.src.sys.uio.writev
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
header: wctype.h
|
||||
standards:
|
||||
- stdc
|
||||
types:
|
||||
- type_name: wint_t
|
||||
- type_name: wctype_t
|
||||
|
|
@ -88,3 +90,15 @@ functions:
|
|||
return_type: wctype_t
|
||||
arguments:
|
||||
- type: const char*
|
||||
- name: towlower
|
||||
standards:
|
||||
- stdc
|
||||
return_type: wint_t
|
||||
arguments:
|
||||
- type: wint_t
|
||||
- name: towupper
|
||||
standards:
|
||||
- stdc
|
||||
return_type: wint_t
|
||||
arguments:
|
||||
- type: wint_t
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ list(APPEND wctype_utils_deps
|
|||
if ("${LIBC_CONF_WCTYPE_MODE}" STREQUAL "LIBC_WCTYPE_MODE_UTF8")
|
||||
list(APPEND wctype_utils_deps
|
||||
libc.src.__support.wctype.wctype_classification_utils
|
||||
libc.src.__support.wctype.wctype_conversion_utils
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -49,3 +49,21 @@ add_object_library(
|
|||
libc.src.__support.CPP.limits
|
||||
libc.src.__support.libc_assert
|
||||
)
|
||||
|
||||
add_object_library(
|
||||
wctype_conversion_utils
|
||||
HDRS
|
||||
wctype_conversion_utils.h
|
||||
SRCS
|
||||
wctype_conversion_utils.cpp
|
||||
COMPILE_OPTIONS
|
||||
"-DLIBC_ENABLE_CONSTEXPR=1"
|
||||
DEPENDS
|
||||
libc.hdr.types.wchar_t
|
||||
libc.hdr.types.wint_t
|
||||
libc.src.__support.macros.attributes
|
||||
libc.src.__support.macros.config
|
||||
.lower_to_upper
|
||||
.upper_to_lower
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_WCTYPE_PERFECT_HASH_MAP_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_WCTYPE_PERFECT_HASH_MAP_H
|
||||
|
||||
#define LIBC_ENABLE_CONSTEXPR 1
|
||||
|
||||
#include "hdr/types/size_t.h"
|
||||
#include "hdr/types/wint_t.h"
|
||||
#include "src/__support/CPP/array.h"
|
||||
|
|
@ -29,8 +27,6 @@
|
|||
#include "src/__support/OSUtil/io.h"
|
||||
#endif
|
||||
|
||||
#undef LIBC_ENABLE_CONSTEXPR
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace wctype_internal {
|
||||
|
||||
|
|
|
|||
46
libc/src/__support/wctype/wctype_conversion_utils.cpp
Normal file
46
libc/src/__support/wctype/wctype_conversion_utils.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Implementation of wctype conversion helpers.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "wctype_conversion_utils.h"
|
||||
#include "lower_to_upper.h"
|
||||
#include "upper_to_lower.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace wctype_internal {
|
||||
|
||||
wint_t tolower(wchar_t wch) {
|
||||
if (auto mapped = UPPER_TO_LOWER_MAP.find(wch)) {
|
||||
return mapped.value();
|
||||
}
|
||||
#if WINT_MAX > 0xFFFF
|
||||
if (auto mapped = UPPER_TO_LOWER_MAP_32.find(wch)) {
|
||||
return mapped.value();
|
||||
}
|
||||
#endif
|
||||
return wch;
|
||||
}
|
||||
|
||||
wint_t toupper(wchar_t wch) {
|
||||
if (auto mapped = LOWER_TO_UPPER_MAP.find(wch)) {
|
||||
return mapped.value();
|
||||
}
|
||||
#if WINT_MAX > 0xFFFF
|
||||
if (auto mapped = LOWER_TO_UPPER_MAP_32.find(wch)) {
|
||||
return mapped.value();
|
||||
}
|
||||
#endif
|
||||
return wch;
|
||||
}
|
||||
|
||||
} // namespace wctype_internal
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
34
libc/src/__support/wctype/wctype_conversion_utils.h
Normal file
34
libc/src/__support/wctype/wctype_conversion_utils.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Interface for wctype conversion functions.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC___SUPPORT_WCTYPE_WCTYPE_CONVERSION_UTILS_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_WCTYPE_WCTYPE_CONVERSION_UTILS_H
|
||||
|
||||
#include "hdr/types/wchar_t.h"
|
||||
#include "hdr/types/wint_t.h"
|
||||
#include "src/__support/macros/attributes.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace wctype_internal {
|
||||
|
||||
// Helper functions for non-ASCII case conversions.
|
||||
// These are implemented in wctype_conversion_utils.cpp using the generated
|
||||
// maps.
|
||||
wint_t tolower(wchar_t wch);
|
||||
wint_t toupper(wchar_t wch);
|
||||
|
||||
} // namespace wctype_internal
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC___SUPPORT_WCTYPE_WCTYPE_CONVERSION_UTILS_H
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#if LIBC_CONF_WCTYPE_MODE == LIBC_WCTYPE_MODE_UTF8
|
||||
#include "src/__support/wctype/wctype_classification_utils.h"
|
||||
#include "src/__support/wctype/wctype_conversion_utils.h"
|
||||
#endif
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
|
@ -585,8 +586,7 @@ LIBC_INLINE constexpr wchar_t tolower(wchar_t wch) {
|
|||
if (static_cast<uint32_t>(wch) < 128) {
|
||||
return ascii::tolower(wch);
|
||||
}
|
||||
// TODO: Add UTF8 implementation.
|
||||
return wch;
|
||||
return static_cast<wchar_t>(wctype_internal::tolower(wch));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -597,8 +597,7 @@ LIBC_INLINE constexpr wchar_t toupper(wchar_t wch) {
|
|||
if (static_cast<uint32_t>(wch) < 128) {
|
||||
return ascii::toupper(wch);
|
||||
}
|
||||
// TODO: Add UTF8 implementation.
|
||||
return wch;
|
||||
return static_cast<wchar_t>(wctype_internal::toupper(wch));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,3 +153,27 @@ add_entrypoint_object(
|
|||
libc.src.__support.wctype_impl
|
||||
libc.hdr.types.wctype_t
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
towlower
|
||||
SRCS
|
||||
towlower.cpp
|
||||
HDRS
|
||||
towlower.h
|
||||
DEPENDS
|
||||
libc.hdr.types.wint_t
|
||||
libc.src.__support.common
|
||||
libc.src.__support.wctype_utils
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
towupper
|
||||
SRCS
|
||||
towupper.cpp
|
||||
HDRS
|
||||
towupper.h
|
||||
DEPENDS
|
||||
libc.hdr.types.wint_t
|
||||
libc.src.__support.common
|
||||
libc.src.__support.wctype_utils
|
||||
)
|
||||
|
|
|
|||
27
libc/src/wctype/towlower.cpp
Normal file
27
libc/src/wctype/towlower.cpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Implementation of towlower.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/wctype/towlower.h"
|
||||
#include "hdr/types/wint_t.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/wctype_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(wint_t, towlower, (wint_t c)) {
|
||||
if (c == static_cast<wint_t>(static_cast<wchar_t>(c)))
|
||||
return static_cast<wint_t>(internal::tolower(static_cast<wchar_t>(c)));
|
||||
return c;
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
26
libc/src/wctype/towlower.h
Normal file
26
libc/src/wctype/towlower.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Implementation header for towlower.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_WCTYPE_TOWLOWER_H
|
||||
#define LLVM_LIBC_SRC_WCTYPE_TOWLOWER_H
|
||||
|
||||
#include "hdr/types/wint_t.h"
|
||||
#include "src/__support/common.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
wint_t towlower(wint_t c);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_WCTYPE_TOWLOWER_H
|
||||
27
libc/src/wctype/towupper.cpp
Normal file
27
libc/src/wctype/towupper.cpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Implementation of towupper.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/wctype/towupper.h"
|
||||
#include "hdr/types/wint_t.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/wctype_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(wint_t, towupper, (wint_t c)) {
|
||||
if (c == static_cast<wint_t>(static_cast<wchar_t>(c)))
|
||||
return static_cast<wint_t>(internal::toupper(static_cast<wchar_t>(c)));
|
||||
return c;
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
26
libc/src/wctype/towupper.h
Normal file
26
libc/src/wctype/towupper.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Implementation header for towupper.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_WCTYPE_TOWUPPER_H
|
||||
#define LLVM_LIBC_SRC_WCTYPE_TOWUPPER_H
|
||||
|
||||
#include "hdr/types/wint_t.h"
|
||||
#include "src/__support/common.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
wint_t towupper(wint_t c);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_WCTYPE_TOWUPPER_H
|
||||
|
|
@ -23,6 +23,7 @@ add_libc_test(
|
|||
SRCS
|
||||
wctype_perfect_hash_test.cpp
|
||||
COMPILE_OPTIONS
|
||||
-DLIBC_ENABLE_CONSTEXPR=1
|
||||
${CONSTEXPR_FLAGS}
|
||||
DEPENDS
|
||||
libc.src.__support.wctype.lower_to_upper
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "hdr/types/wctype_t.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/wctype/wctype_classification_utils.h"
|
||||
#include "src/__support/wctype/wctype_conversion_utils.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
namespace {
|
||||
|
||||
|
|
@ -32,6 +33,10 @@ namespace utf8_mode {
|
|||
namespace LIBC_NAMESPACE_DECL {
|
||||
using ::LIBC_NAMESPACE::lookup_properties;
|
||||
using ::LIBC_NAMESPACE::PropertyFlag;
|
||||
namespace wctype_internal {
|
||||
using ::LIBC_NAMESPACE::wctype_internal::tolower;
|
||||
using ::LIBC_NAMESPACE::wctype_internal::toupper;
|
||||
} // namespace wctype_internal
|
||||
namespace cpp = ::LIBC_NAMESPACE::cpp;
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ add_libc_test(
|
|||
libc.src.wctype.iswgraph
|
||||
)
|
||||
|
||||
add_libc_test(
|
||||
add_libc_test(
|
||||
iswlower_test
|
||||
SUITE
|
||||
libc_wctype_unittests
|
||||
|
|
@ -142,3 +142,27 @@ add_libc_test(
|
|||
DEPENDS
|
||||
libc.src.wctype.wctype
|
||||
)
|
||||
|
||||
add_libc_test(
|
||||
towlower_test
|
||||
SUITE
|
||||
libc_wctype_unittests
|
||||
SRCS
|
||||
towlower_test.cpp
|
||||
DEPENDS
|
||||
libc.hdr.wchar_macros
|
||||
libc.src.wctype.towlower
|
||||
libc.src.__support.wctype_utils
|
||||
)
|
||||
|
||||
add_libc_test(
|
||||
towupper_test
|
||||
SUITE
|
||||
libc_wctype_unittests
|
||||
SRCS
|
||||
towupper_test.cpp
|
||||
DEPENDS
|
||||
libc.hdr.wchar_macros
|
||||
libc.src.wctype.towupper
|
||||
libc.src.__support.wctype_utils
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/wctype_utils.h"
|
||||
#include "src/wctype/iswprint.h"
|
||||
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
|
@ -15,7 +16,21 @@ TEST(LlvmLibciswprint, SimpleTest) {
|
|||
if (' ' <= ch && ch <= '~') {
|
||||
EXPECT_NE(LIBC_NAMESPACE::iswprint(ch), 0);
|
||||
} else {
|
||||
#if LIBC_CONF_WCTYPE_MODE == LIBC_WCTYPE_MODE_UTF8
|
||||
// In UTF-8 mode, characters above 127 can be printable.
|
||||
if (ch < 128) {
|
||||
EXPECT_EQ(LIBC_NAMESPACE::iswprint(ch), 0);
|
||||
}
|
||||
#else
|
||||
// In ASCII mode, everything outside ASCII printable is not printable.
|
||||
EXPECT_EQ(LIBC_NAMESPACE::iswprint(ch), 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if LIBC_CONF_WCTYPE_MODE == LIBC_WCTYPE_MODE_UTF8
|
||||
EXPECT_NE(LIBC_NAMESPACE::iswprint(L'á'), 0);
|
||||
#else
|
||||
EXPECT_EQ(LIBC_NAMESPACE::iswprint(L'á'), 0);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
85
libc/test/src/wctype/towlower_test.cpp
Normal file
85
libc/test/src/wctype/towlower_test.cpp
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Unit tests for towlower.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "hdr/wchar_macros.h" // for WEOF
|
||||
#include "src/__support/wctype_utils.h"
|
||||
#include "src/wctype/towlower.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
||||
TEST(LlvmLibcTowLower, SimpleTest) {
|
||||
// ASCII Conversions
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'A'), static_cast<wint_t>(L'a'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'Z'), static_cast<wint_t>(L'z'));
|
||||
|
||||
// ASCII Unchanged
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'a'), static_cast<wint_t>(L'a'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'z'), static_cast<wint_t>(L'z'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'1'), static_cast<wint_t>(L'1'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'\0'), static_cast<wint_t>(L'\0'));
|
||||
|
||||
// WEOF Test
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(WEOF), static_cast<wint_t>(WEOF));
|
||||
|
||||
// Boundary / Out-of-domain Tests (should return unchanged)
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(0xFFFF), static_cast<wint_t>(0xFFFF));
|
||||
#if WCHAR_MAX > 0xFFFF
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(0x110000), static_cast<wint_t>(0x110000));
|
||||
#endif
|
||||
|
||||
// Non-ASCII Lowercase (Already lowercase: should remain unchanged
|
||||
// unconditionally in BOTH modes)
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'α'), static_cast<wint_t>(L'α'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'а'), static_cast<wint_t>(L'а'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'é'), static_cast<wint_t>(L'é'));
|
||||
}
|
||||
|
||||
#if LIBC_CONF_WCTYPE_MODE == LIBC_WCTYPE_MODE_UTF8
|
||||
TEST(LlvmLibcTowLower, NonAsciiTestUtf8) {
|
||||
// Greek conversions
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'Α'), static_cast<wint_t>(L'α')); // alpha
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'Ω'), static_cast<wint_t>(L'ω')); // omega
|
||||
|
||||
// Cyrillic conversions
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'А'), static_cast<wint_t>(L'а')); // A
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'Я'), static_cast<wint_t>(L'я')); // Ya
|
||||
|
||||
// Accented Latin
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'É'), static_cast<wint_t>(L'é'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'Ü'), static_cast<wint_t>(L'ü'));
|
||||
|
||||
#if WCHAR_MAX > 0xFFFF
|
||||
// Deseret (Unicode Plane 1) conversions
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'\U00010400'),
|
||||
static_cast<wint_t>(L'\U00010428'));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LIBC_CONF_WCTYPE_MODE == LIBC_WCTYPE_MODE_ASCII
|
||||
TEST(LlvmLibcTowLower, NonAsciiTestAscii) {
|
||||
// Non-ASCII uppercase characters must return unchanged under ASCII-only mode
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'Α'), static_cast<wint_t>(L'Α'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'Ω'), static_cast<wint_t>(L'Ω'));
|
||||
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'А'), static_cast<wint_t>(L'А'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'Я'), static_cast<wint_t>(L'Я'));
|
||||
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'É'), static_cast<wint_t>(L'É'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'Ü'), static_cast<wint_t>(L'Ü'));
|
||||
|
||||
#if WCHAR_MAX > 0xFFFF
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towlower(L'\U00010400'),
|
||||
static_cast<wint_t>(L'\U00010400'));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
85
libc/test/src/wctype/towupper_test.cpp
Normal file
85
libc/test/src/wctype/towupper_test.cpp
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Unit tests for towupper.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "hdr/wchar_macros.h" // for WEOF
|
||||
#include "src/__support/wctype_utils.h"
|
||||
#include "src/wctype/towupper.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
||||
TEST(LlvmLibcTowUpper, SimpleTest) {
|
||||
// ASCII Conversions
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'a'), static_cast<wint_t>(L'A'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'z'), static_cast<wint_t>(L'Z'));
|
||||
|
||||
// ASCII Unchanged
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'A'), static_cast<wint_t>(L'A'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'Z'), static_cast<wint_t>(L'Z'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'1'), static_cast<wint_t>(L'1'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'\0'), static_cast<wint_t>(L'\0'));
|
||||
|
||||
// WEOF Test
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(WEOF), static_cast<wint_t>(WEOF));
|
||||
|
||||
// Boundary / Out-of-domain Tests (should return unchanged)
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(0xFFFF), static_cast<wint_t>(0xFFFF));
|
||||
#if WCHAR_MAX > 0xFFFF
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(0x110000), static_cast<wint_t>(0x110000));
|
||||
#endif
|
||||
|
||||
// Non-ASCII Uppercase (Already uppercase: should remain unchanged
|
||||
// unconditionally in BOTH modes)
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'Α'), static_cast<wint_t>(L'Α'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'А'), static_cast<wint_t>(L'А'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'É'), static_cast<wint_t>(L'É'));
|
||||
}
|
||||
|
||||
#if LIBC_CONF_WCTYPE_MODE == LIBC_WCTYPE_MODE_UTF8
|
||||
TEST(LlvmLibcTowUpper, NonAsciiTestUtf8) {
|
||||
// Greek conversions
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'α'), static_cast<wint_t>(L'Α')); // alpha
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'ω'), static_cast<wint_t>(L'Ω')); // omega
|
||||
|
||||
// Cyrillic conversions
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'а'), static_cast<wint_t>(L'А')); // A
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'я'), static_cast<wint_t>(L'Я')); // Ya
|
||||
|
||||
// Accented Latin
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'é'), static_cast<wint_t>(L'É'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'ü'), static_cast<wint_t>(L'Ü'));
|
||||
|
||||
#if WCHAR_MAX > 0xFFFF
|
||||
// Deseret (Unicode Plane 1) conversions
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'\U00010428'),
|
||||
static_cast<wint_t>(L'\U00010400'));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LIBC_CONF_WCTYPE_MODE == LIBC_WCTYPE_MODE_ASCII
|
||||
TEST(LlvmLibcTowUpper, NonAsciiTestAscii) {
|
||||
// Non-ASCII lowercase characters must return unchanged under ASCII-only mode
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'α'), static_cast<wint_t>(L'α'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'ω'), static_cast<wint_t>(L'ω'));
|
||||
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'а'), static_cast<wint_t>(L'а'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'я'), static_cast<wint_t>(L'я'));
|
||||
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'é'), static_cast<wint_t>(L'é'));
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'ü'), static_cast<wint_t>(L'ü'));
|
||||
|
||||
#if WCHAR_MAX > 0xFFFF
|
||||
EXPECT_EQ(LIBC_NAMESPACE::towupper(L'\U00010428'),
|
||||
static_cast<wint_t>(L'\U00010428'));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
Loading…
Reference in a new issue