mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-14 11:39:35 +00:00
[libc++][format] Fixes year formatter on Windows.
Windows' libc, like some other libc implementations do not work as specified for %Y and %y. This uses the fixes used for other libc implementations. The work was part of D150593. Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D151612
This commit is contained in:
parent
66c7388c83
commit
0ee73debf7
@ -270,20 +270,19 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
|
||||
//
|
||||
// TODO FMT evaluate the comment above.
|
||||
|
||||
# if defined(__GLIBC__) || defined(_AIX)
|
||||
# if defined(__GLIBC__) || defined(_AIX) || defined(_WIN32)
|
||||
case _CharT('y'):
|
||||
// Glibc fails for negative values, AIX for positive values too.
|
||||
__sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), (std::abs(__t.tm_year + 1900)) % 100);
|
||||
break;
|
||||
# endif // defined(__GLIBC__) || defined(_AIX)
|
||||
# endif // defined(__GLIBC__) || defined(_AIX) || defined(_WIN32)
|
||||
|
||||
case _CharT('Y'): {
|
||||
int __year = __t.tm_year + 1900;
|
||||
if (__year < 1000)
|
||||
__formatter::__format_year(__year, __sstr);
|
||||
else
|
||||
__facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
|
||||
} break;
|
||||
case _CharT('Y'):
|
||||
// Depending on the platform's libc the range of supported years is
|
||||
// limited. Intead of of testing all conditions use the internal
|
||||
// implementation unconditionally.
|
||||
__formatter::__format_year(__t.tm_year + 1900, __sstr);
|
||||
break;
|
||||
|
||||
case _CharT('F'): {
|
||||
int __year = __t.tm_year + 1900;
|
||||
|
@ -9,9 +9,6 @@
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-localization
|
||||
|
||||
// TODO FMT Investigate Windows issues.
|
||||
// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
|
||||
|
||||
// TODO FMT Fix this test using GCC, it currently crashes.
|
||||
// UNSUPPORTED: gcc-12
|
||||
|
||||
@ -35,9 +32,16 @@
|
||||
#include "make_string.h"
|
||||
#include "platform_support.h" // locale name macros
|
||||
#include "test_macros.h"
|
||||
#include "assert_macros.h"
|
||||
#include "concat_macros.h"
|
||||
|
||||
#define SV(S) MAKE_STRING_VIEW(CharT, S)
|
||||
|
||||
#define TEST_EQUAL(OUT, EXPECTED) \
|
||||
TEST_REQUIRE(OUT == EXPECTED, \
|
||||
TEST_WRITE_CONCATENATED( \
|
||||
"\nExpression ", #OUT, "\nExpected output ", EXPECTED, "\nActual output ", OUT, '\n'));
|
||||
|
||||
template <class CharT>
|
||||
static std::basic_string<CharT> stream_c_locale(std::chrono::year year) {
|
||||
std::basic_stringstream<CharT> sstr;
|
||||
@ -65,23 +69,23 @@ static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::year year) {
|
||||
|
||||
template <class CharT>
|
||||
static void test() {
|
||||
assert(stream_c_locale<CharT>(std::chrono::year{-32'768}) == SV("-32768 is not a valid year"));
|
||||
assert(stream_c_locale<CharT>(std::chrono::year{-32'767}) == SV("-32767"));
|
||||
assert(stream_c_locale<CharT>(std::chrono::year{0}) == SV("0000"));
|
||||
assert(stream_c_locale<CharT>(std::chrono::year{1970}) == SV("1970"));
|
||||
assert(stream_c_locale<CharT>(std::chrono::year{32'767}) == SV("32767"));
|
||||
TEST_EQUAL(stream_c_locale<CharT>(std::chrono::year{-32'768}), SV("-32768 is not a valid year"));
|
||||
TEST_EQUAL(stream_c_locale<CharT>(std::chrono::year{-32'767}), SV("-32767"));
|
||||
TEST_EQUAL(stream_c_locale<CharT>(std::chrono::year{0}), SV("0000"));
|
||||
TEST_EQUAL(stream_c_locale<CharT>(std::chrono::year{1970}), SV("1970"));
|
||||
TEST_EQUAL(stream_c_locale<CharT>(std::chrono::year{32'767}), SV("32767"));
|
||||
|
||||
assert(stream_fr_FR_locale<CharT>(std::chrono::year{-32'768}) == SV("-32768 is not a valid year"));
|
||||
assert(stream_fr_FR_locale<CharT>(std::chrono::year{-32'767}) == SV("-32767"));
|
||||
assert(stream_fr_FR_locale<CharT>(std::chrono::year{0}) == SV("0000"));
|
||||
assert(stream_fr_FR_locale<CharT>(std::chrono::year{1970}) == SV("1970"));
|
||||
assert(stream_fr_FR_locale<CharT>(std::chrono::year{32'767}) == SV("32767"));
|
||||
TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::year{-32'768}), SV("-32768 is not a valid year"));
|
||||
TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::year{-32'767}), SV("-32767"));
|
||||
TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::year{0}), SV("0000"));
|
||||
TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::year{1970}), SV("1970"));
|
||||
TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::year{32'767}), SV("32767"));
|
||||
|
||||
assert(stream_ja_JP_locale<CharT>(std::chrono::year{-32'768}) == SV("-32768 is not a valid year"));
|
||||
assert(stream_ja_JP_locale<CharT>(std::chrono::year{-32'767}) == SV("-32767"));
|
||||
assert(stream_ja_JP_locale<CharT>(std::chrono::year{0}) == SV("0000"));
|
||||
assert(stream_ja_JP_locale<CharT>(std::chrono::year{1970}) == SV("1970"));
|
||||
assert(stream_ja_JP_locale<CharT>(std::chrono::year{32'767}) == SV("32767"));
|
||||
TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::year{-32'768}), SV("-32768 is not a valid year"));
|
||||
TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::year{-32'767}), SV("-32767"));
|
||||
TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::year{0}), SV("0000"));
|
||||
TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::year{1970}), SV("1970"));
|
||||
TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::year{32'767}), SV("32767"));
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
|
@ -10,9 +10,6 @@
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-localization
|
||||
|
||||
// TODO FMT Investigate Windows issues.
|
||||
// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
|
||||
|
||||
// TODO FMT Fix this test using GCC, it currently crashes.
|
||||
// UNSUPPORTED: gcc-12
|
||||
|
||||
@ -88,7 +85,7 @@ static void test_valid_values() {
|
||||
|
||||
// Non localized output using C-locale
|
||||
check(SV("%C='00'\t"
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
"%EC='00'\t"
|
||||
#else
|
||||
"%EC='0'\t"
|
||||
@ -97,7 +94,7 @@ static void test_valid_values() {
|
||||
"%Ey='00'\t"
|
||||
"%Oy='00'\t"
|
||||
"%Y='0000'\t"
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
"%EY='0000'\t"
|
||||
#elif defined(_AIX)
|
||||
"%EY=''\t"
|
||||
@ -132,7 +129,7 @@ static void test_valid_values() {
|
||||
|
||||
// Use the global locale (fr_FR)
|
||||
check(SV("%C='00'\t"
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
"%EC='00'\t"
|
||||
#else
|
||||
"%EC='0'\t"
|
||||
@ -141,7 +138,7 @@ static void test_valid_values() {
|
||||
"%Ey='00'\t"
|
||||
"%Oy='00'\t"
|
||||
"%Y='0000'\t"
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
"%EY='0000'\t"
|
||||
#elif defined(_AIX)
|
||||
"%EY=''\t"
|
||||
@ -175,10 +172,10 @@ static void test_valid_values() {
|
||||
std::chrono::year{2038});
|
||||
|
||||
// Use supplied locale (ja_JP). This locale has a different alternate.
|
||||
#if defined(__APPLE__) || defined(_AIX)
|
||||
#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
|
||||
|
||||
check(SV("%C='00'\t"
|
||||
# if defined(__APPLE__)
|
||||
# if defined(__APPLE__) || defined(_WIN32)
|
||||
"%EC='00'\t"
|
||||
# else
|
||||
"%EC='0'\t"
|
||||
@ -218,12 +215,12 @@ static void test_valid_values() {
|
||||
lfmt,
|
||||
std::chrono::year{2038});
|
||||
|
||||
#else // defined(__APPLE__) || defined(_AIX)
|
||||
#else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
|
||||
check(loc,
|
||||
SV("%C='00'\t"
|
||||
"%EC='紀元前'\t"
|
||||
"%y='00'\t"
|
||||
// https://sourceware.org/bugzilla/show_bug.cgi?id=23758
|
||||
// https://sourceware.org/bugzilla/show_bug.cgi?id=23758
|
||||
# if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29
|
||||
"%Ey='1'\t"
|
||||
# else
|
||||
@ -231,7 +228,7 @@ static void test_valid_values() {
|
||||
# endif
|
||||
"%Oy='〇'\t"
|
||||
"%Y='0000'\t"
|
||||
// https://sourceware.org/bugzilla/show_bug.cgi?id=23758
|
||||
// https://sourceware.org/bugzilla/show_bug.cgi?id=23758
|
||||
# if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29
|
||||
"%EY='紀元前1年'\t"
|
||||
# else
|
||||
@ -265,7 +262,7 @@ static void test_valid_values() {
|
||||
"\n"),
|
||||
lfmt,
|
||||
std::chrono::year{2038});
|
||||
#endif // defined(__APPLE__) || defined(_AIX)
|
||||
#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
|
||||
|
||||
std::locale::global(std::locale::classic());
|
||||
}
|
||||
@ -273,7 +270,6 @@ static void test_valid_values() {
|
||||
template <class CharT>
|
||||
static void test_padding() {
|
||||
constexpr std::basic_string_view<CharT> fmt = SV("{:%%C='%C'%t%%y='%y'%t%%Y='%Y'%t%n}");
|
||||
|
||||
check(SV("%C='-100'\t%y='99'\t%Y='-9999'\t\n"), fmt, std::chrono::year{-9'999});
|
||||
check(SV("%C='-10'\t%y='99'\t%Y='-0999'\t\n"), fmt, std::chrono::year{-999});
|
||||
check(SV("%C='-1'\t%y='99'\t%Y='-0099'\t\n"), fmt, std::chrono::year{-99});
|
||||
|
Loading…
Reference in New Issue
Block a user