forked from OSchip/llvm-project
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
This commit is contained in:
parent
7d3aba6687
commit
fcc1e6d978
|
@ -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;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "test_iterators.h"
|
||||
|
||||
#include "platform_support.h" // locale name macros
|
||||
#include "test_macros.h"
|
||||
|
||||
typedef std::money_get<char, input_iterator<const char*> > 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> 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<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "test_iterators.h"
|
||||
|
||||
#include "platform_support.h" // locale name macros
|
||||
#include "test_macros.h"
|
||||
|
||||
typedef std::money_put<char, output_iterator<char*> > 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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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<wchar_t*> iter = f.put(output_iterator<wchar_t*>(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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <locale>
|
||||
#include <limits>
|
||||
#include <cassert>
|
||||
#include <iostream> // 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);
|
||||
}
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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',';
|
||||
|
|
Loading…
Reference in New Issue