[libcxx] r329143 - Fix locale test data for GLIBC 2.27 and newer.

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 3 21:00:14 PDT 2018


Author: ericwf
Date: Tue Apr  3 21:00:14 2018
New Revision: 329143

URL: http://llvm.org/viewvc/llvm-project?rev=329143&view=rev
Log:
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.

Modified:
    libcxx/trunk/src/locale.cpp
    libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
    libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
    libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp
    libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
    libcxx/trunk/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp

Modified: libcxx/trunk/src/locale.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/locale.cpp?rev=329143&r1=329142&r2=329143&view=diff
==============================================================================
--- libcxx/trunk/src/locale.cpp (original)
+++ libcxx/trunk/src/locale.cpp Tue Apr  3 21:00:14 2018
@@ -4240,6 +4240,7 @@ static bool checked_string_to_char_conve
   // 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;

Modified: libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp?rev=329143&r1=329142&r2=329143&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp Tue Apr  3 21:00:14 2018
@@ -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;

Modified: libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp?rev=329143&r1=329142&r2=329143&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp Tue Apr  3 21:00:14 2018
@@ -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);
     }
 }

Modified: libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp?rev=329143&r1=329142&r2=329143&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp Tue Apr  3 21:00:14 2018
@@ -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);
     }
     {

Modified: libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp?rev=329143&r1=329142&r2=329143&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp Tue Apr  3 21:00:14 2018
@@ -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.

Modified: libcxx/trunk/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp?rev=329143&r1=329142&r2=329143&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp Tue Apr  3 21:00:14 2018
@@ -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',';




More information about the cfe-commits mailing list