From: Eric Fiselier Date: Wed, 4 Apr 2018 04:00:14 +0000 (+0000) Subject: Fix locale test data for GLIBC 2.27 and newer. X-Git-Tag: llvmorg-7.0.0-rc1~9050 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fcc1e6d978d4333426aa710af3d00c1db6a705da;p=platform%2Fupstream%2Fllvm.git Fix locale test data for GLIBC 2.27 and newer. GLIBC 2.27 changed the locale data for fr_FR and ru_RU. In particular they change the decimal and thousands separators used. This patch makes the locale tests tolerate the updated locales. llvm-svn: 329143 --- diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp index 11f864a..b9c7011 100644 --- a/libcxx/src/locale.cpp +++ b/libcxx/src/locale.cpp @@ -4240,6 +4240,7 @@ static bool checked_string_to_char_convert(char& dest, // FIXME: Work around specific multibyte sequences that we can reasonable // translate into a different single byte. switch (wout) { + case L'\u202F': // narrow non-breaking space case L'\u00A0': // non-breaking space dest = ' '; return true; diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp index 5656f73..7d1fee4 100644 --- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp @@ -25,6 +25,7 @@ #include "test_iterators.h" #include "platform_support.h" // locale name macros +#include "test_macros.h" typedef std::money_get > Fn; @@ -46,6 +47,30 @@ public: : Fw(refs) {} }; + +// GLIBC 2.27 and newer use U2027 (narrow non-breaking space) as a thousands sep. +// this function converts the spaces in string inputs to that character if need +// be. +static std::wstring convert_thousands_sep(std::wstring const& in) { +#if !defined(TEST_HAS_GLIBC) || !TEST_GLIBC_PREREQ(2,27) + return in; +#else + std::wstring out; + unsigned I = 0; + bool seen_decimal = false; + for (; I < in.size(); ++I) { + if (seen_decimal || in[I] != L' ') { + seen_decimal |= in[I] == L','; + out.push_back(in[I]); + continue; + } + assert(in[I] == L' '); + out.push_back(L'\u202F'); + } + return out; +#endif +} + int main() { std::ios ios(0); @@ -417,7 +442,7 @@ int main() assert(ex == -1); } { // positive - std::wstring v = L"1 234 567,89 "; + std::wstring v = convert_thousands_sep(L"1 234 567,89 "); typedef input_iterator I; long double ex; std::ios_base::iostate err = std::ios_base::goodbit; @@ -428,7 +453,7 @@ int main() assert(ex == 123456789); } { // negative - std::wstring v = L"-1 234 567,89"; + std::wstring v = convert_thousands_sep(L"-1 234 567,89"); typedef input_iterator I; long double ex; std::ios_base::iostate err = std::ios_base::goodbit; @@ -497,7 +522,7 @@ int main() assert(ex == -1); } { // positive, showbase - std::wstring v = L"1 234 567,89 \u20ac"; // EURO SIGN + std::wstring v = convert_thousands_sep(L"1 234 567,89 \u20ac"); // EURO SIGN typedef input_iterator I; long double ex; std::ios_base::iostate err = std::ios_base::goodbit; @@ -508,7 +533,7 @@ int main() assert(ex == 123456789); } { // positive, showbase - std::wstring v = L"1 234 567,89 \u20ac"; // EURO SIGN + std::wstring v = convert_thousands_sep(L"1 234 567,89 \u20ac"); // EURO SIGN showbase(ios); typedef input_iterator I; long double ex; @@ -521,7 +546,7 @@ int main() noshowbase(ios); } { // negative, showbase - std::wstring v = L"-1 234 567,89 \u20ac"; // EURO SIGN + std::wstring v = convert_thousands_sep(L"-1 234 567,89 \u20ac"); // EURO SIGN showbase(ios); typedef input_iterator I; long double ex; @@ -534,7 +559,7 @@ int main() noshowbase(ios); } { // negative, showbase - std::wstring v = L"1 234 567,89 EUR -"; + std::wstring v = convert_thousands_sep(L"1 234 567,89 EUR -"); showbase(ios); typedef input_iterator I; long double ex; @@ -546,7 +571,7 @@ int main() noshowbase(ios); } { // negative, showbase - std::wstring v = L"1 234 567,89 EUR -"; + std::wstring v = convert_thousands_sep(L"1 234 567,89 EUR -"); typedef input_iterator I; long double ex; std::ios_base::iostate err = std::ios_base::goodbit; @@ -583,7 +608,7 @@ int main() assert(ex == -1); } { // positive - std::wstring v = L"1 234 567,89 "; + std::wstring v = convert_thousands_sep(L"1 234 567,89 "); typedef input_iterator I; long double ex; std::ios_base::iostate err = std::ios_base::goodbit; @@ -594,7 +619,7 @@ int main() assert(ex == 123456789); } { // negative - std::wstring v = L"-1 234 567,89"; + std::wstring v = convert_thousands_sep(L"-1 234 567,89"); typedef input_iterator I; long double ex; std::ios_base::iostate err = std::ios_base::goodbit; @@ -663,7 +688,7 @@ int main() assert(ex == -1); } { // positive, showbase - std::wstring v = L"1 234 567,89 EUR"; + std::wstring v = convert_thousands_sep(L"1 234 567,89 EUR"); typedef input_iterator I; long double ex; std::ios_base::iostate err = std::ios_base::goodbit; @@ -674,7 +699,7 @@ int main() assert(ex == 123456789); } { // positive, showbase - std::wstring v = L"1 234 567,89 EUR"; + std::wstring v = convert_thousands_sep(L"1 234 567,89 EUR"); showbase(ios); typedef input_iterator I; long double ex; @@ -687,7 +712,7 @@ int main() noshowbase(ios); } { // negative, showbase - std::wstring v = L"-1 234 567,89 EUR"; + std::wstring v = convert_thousands_sep(L"-1 234 567,89 EUR"); showbase(ios); typedef input_iterator I; long double ex; @@ -700,7 +725,7 @@ int main() noshowbase(ios); } { // negative, showbase - std::wstring v = L"1 234 567,89 Eu-"; + std::wstring v = convert_thousands_sep(L"1 234 567,89 Eu-"); showbase(ios); typedef input_iterator I; long double ex; @@ -712,7 +737,7 @@ int main() noshowbase(ios); } { // negative, showbase - std::wstring v = L"1 234 567,89 Eu-"; + std::wstring v = convert_thousands_sep(L"1 234 567,89 Eu-"); typedef input_iterator I; long double ex; std::ios_base::iostate err = std::ios_base::goodbit; diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp index 8b620bc..acad6e3 100644 --- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp @@ -25,6 +25,7 @@ #include "test_iterators.h" #include "platform_support.h" // locale name macros +#include "test_macros.h" typedef std::money_put > Fn; @@ -46,6 +47,32 @@ public: : Fw(refs) {} }; + +// GLIBC 2.27 and newer use U2027 (narrow non-breaking space) as a thousands sep. +// this function converts the spaces in string inputs to that character if need +// be. +static std::wstring convert_thousands_sep(std::wstring const& in) { +#if !defined(TEST_HAS_GLIBC) || !TEST_GLIBC_PREREQ(2,27) + return in; +#else + std::wstring out; + unsigned I = 0; + bool seen_num_start = false; + bool seen_decimal = false; + for (; I < in.size(); ++I) { + seen_decimal |= in[I] == L','; + seen_num_start |= in[I] == '-' || std::iswdigit(in[I]); + if (seen_decimal || !seen_num_start || in[I] != L' ') { + out.push_back(in[I]); + continue; + } + assert(in[I] == L' '); + out.push_back(L'\u202F'); + } + return out; +#endif +} + int main() { std::ios ios(0); @@ -301,7 +328,7 @@ int main() output_iterator iter = f.put(output_iterator(str), false, ios, '*', v); std::wstring ex(str, iter.base()); - assert(ex == L"1 234 567,89"); + assert(ex == convert_thousands_sep(L"1 234 567,89")); } { // negative long double v = -123456789; @@ -309,7 +336,7 @@ int main() output_iterator iter = f.put(output_iterator(str), false, ios, '*', v); std::wstring ex(str, iter.base()); - assert(ex == L"-1 234 567,89"); + assert(ex == convert_thousands_sep(L"-1 234 567,89")); } { // zero, showbase long double v = 0; @@ -336,7 +363,7 @@ int main() output_iterator iter = f.put(output_iterator(str), false, ios, '*', v); std::wstring ex(str, iter.base()); - assert(ex == L"1 234 567,89 \u20ac"); + assert(ex == convert_thousands_sep(L"1 234 567,89 \u20ac")); } { // negative, showbase long double v = -123456789; @@ -345,7 +372,7 @@ int main() output_iterator iter = f.put(output_iterator(str), false, ios, '*', v); std::wstring ex(str, iter.base()); - assert(ex == L"-1 234 567,89 \u20ac"); + assert(ex == convert_thousands_sep(L"-1 234 567,89 \u20ac")); } { // negative, showbase, left long double v = -123456789; @@ -356,7 +383,7 @@ int main() output_iterator iter = f.put(output_iterator(str), false, ios, ' ', v); std::wstring ex(str, iter.base()); - assert(ex == L"-1 234 567,89 \u20ac "); + assert(ex == convert_thousands_sep(L"-1 234 567,89 \u20ac ")); assert(ios.width() == 0); } { // negative, showbase, internal @@ -368,7 +395,7 @@ int main() output_iterator iter = f.put(output_iterator(str), false, ios, ' ', v); std::wstring ex(str, iter.base()); - assert(ex == L"-1 234 567,89 \u20ac"); + assert(ex == convert_thousands_sep(L"-1 234 567,89 \u20ac")); assert(ios.width() == 0); } { // negative, showbase, right @@ -380,7 +407,7 @@ int main() output_iterator iter = f.put(output_iterator(str), false, ios, ' ', v); std::wstring ex(str, iter.base()); - assert(ex == L" -1 234 567,89 \u20ac"); + assert(ex == convert_thousands_sep(L" -1 234 567,89 \u20ac")); assert(ios.width() == 0); } @@ -409,7 +436,7 @@ int main() output_iterator iter = f.put(output_iterator(str), true, ios, '*', v); std::wstring ex(str, iter.base()); - assert(ex == L"1 234 567,89"); + assert(ex == convert_thousands_sep(L"1 234 567,89")); } { // negative long double v = -123456789; @@ -417,7 +444,7 @@ int main() output_iterator iter = f.put(output_iterator(str), true, ios, '*', v); std::wstring ex(str, iter.base()); - assert(ex == L"-1 234 567,89"); + assert(ex == convert_thousands_sep(L"-1 234 567,89")); } { // zero, showbase long double v = 0; @@ -444,7 +471,7 @@ int main() output_iterator iter = f.put(output_iterator(str), true, ios, '*', v); std::wstring ex(str, iter.base()); - assert(ex == L"1 234 567,89 EUR"); + assert(ex == convert_thousands_sep(L"1 234 567,89 EUR")); } { // negative, showbase long double v = -123456789; @@ -453,7 +480,7 @@ int main() output_iterator iter = f.put(output_iterator(str), true, ios, '*', v); std::wstring ex(str, iter.base()); - assert(ex == L"-1 234 567,89 EUR"); + assert(ex == convert_thousands_sep(L"-1 234 567,89 EUR")); } { // negative, showbase, left long double v = -123456789; @@ -464,7 +491,7 @@ int main() output_iterator iter = f.put(output_iterator(str), true, ios, ' ', v); std::wstring ex(str, iter.base()); - assert(ex == L"-1 234 567,89 EUR "); + assert(ex == convert_thousands_sep(L"-1 234 567,89 EUR ")); assert(ios.width() == 0); } { // negative, showbase, internal @@ -476,7 +503,7 @@ int main() output_iterator iter = f.put(output_iterator(str), true, ios, ' ', v); std::wstring ex(str, iter.base()); - assert(ex == L"-1 234 567,89 EUR"); + assert(ex == convert_thousands_sep(L"-1 234 567,89 EUR")); assert(ios.width() == 0); } { // negative, showbase, right @@ -488,7 +515,7 @@ int main() output_iterator iter = f.put(output_iterator(str), true, ios, ' ', v); std::wstring ex(str, iter.base()); - assert(ex == L" -1 234 567,89 EUR"); + assert(ex == convert_thousands_sep(L" -1 234 567,89 EUR")); assert(ios.width() == 0); } } diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp index 09e6e94..84fc8f8 100644 --- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp @@ -21,7 +21,6 @@ #include #include #include -#include // FIXME: for debugging purposes only #include "test_macros.h" #include "platform_support.h" // locale name macros @@ -111,7 +110,8 @@ int main() assert(f.decimal_point() == L','); } // GLIBC 2.23 uses '.' as the decimal point while other C libraries use ',' -#ifndef TEST_HAS_GLIBC +// GLIBC 2.27 corrects this. +#if !defined(TEST_HAS_GLIBC) || TEST_GLIBC_PREREQ(2, 27) const char sep = ','; const wchar_t wsep = L','; #else @@ -120,11 +120,6 @@ int main() #endif { Fnf f(LOCALE_ru_RU_UTF_8, 1); - if (f.decimal_point() != sep) { - std::cout << "f.decimal_point() = '" << f.decimal_point() << "'\n"; - std::cout << "sep = '" << sep << "'\n"; - std::cout << std::endl; - } assert(f.decimal_point() == sep); } { diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp index aa585a4..4a672a7 100644 --- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp @@ -92,7 +92,6 @@ int main() Fwt f(LOCALE_en_US_UTF_8, 1); assert(f.thousands_sep() == L','); } - { Fnf f(LOCALE_fr_FR_UTF_8, 1); assert(f.thousands_sep() == ' '); @@ -101,13 +100,19 @@ int main() Fnt f(LOCALE_fr_FR_UTF_8, 1); assert(f.thousands_sep() == ' '); } +// The below tests work around GLIBC's use of U202F as mon_thousands_sep. +#if defined(TEST_HAS_GLIBC) && TEST_GLIBC_PREREQ(2, 27) + const wchar_t fr_sep = L'\u202F'; +#else + const wchar_t fr_sep = L' '; +#endif { Fwf f(LOCALE_fr_FR_UTF_8, 1); - assert(f.thousands_sep() == L' '); + assert(f.thousands_sep() == fr_sep); } { Fwt f(LOCALE_fr_FR_UTF_8, 1); - assert(f.thousands_sep() == L' '); + assert(f.thousands_sep() == fr_sep); } // The below tests work around GLIBC's use of U00A0 as mon_thousands_sep // and U002E as mon_decimal_point. @@ -116,6 +121,11 @@ int main() #ifndef TEST_HAS_GLIBC const char sep = ' '; const wchar_t wsep = L' '; +#elif TEST_GLIBC_PREREQ(2, 27) + // FIXME libc++ specifically works around \u00A0 by translating it into + // a regular space. + const char sep = ' '; + const wchar_t wsep = L'\u202F'; #else // FIXME libc++ specifically works around \u00A0 by translating it into // a regular space. diff --git a/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp b/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp index 08ce35b..0dedf78 100644 --- a/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp @@ -56,7 +56,12 @@ int main() std::locale l(LOCALE_fr_FR_UTF_8); #if defined(TEST_HAS_GLIBC) const char sep = ' '; +// The below tests work around GLIBC's use of U202F as LC_NUMERIC thousands_sep. +# if TEST_GLIBC_PREREQ(2, 27) + const wchar_t wsep = L'\u202f'; +# else const wchar_t wsep = L' '; +# endif #else const char sep = ','; const wchar_t wsep = L',';