https://gcc.gnu.org/g:39236ff82627398dec4b30964f540d0a223be200

commit r13-9135-g39236ff82627398dec4b30964f540d0a223be200
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Tue Sep 24 23:20:56 2024 +0100

    libstdc++: Populate std::time_get::get's %c format for C locale
    
    We were using the empty string "" for D_T_FMT and ERA_D_T_FMT in the C
    locale, instead of "%a %b %e %T %Y" as the C standard requires. Set it
    correctly for each locale implementation that defines time_members.cc.
    
    We can also explicitly set the _M_era_xxx pointers to the same values as
    the corresponding _M_xxx ones, rather than setting them to point to
    identical string literals. This doesn't rely on the compiler merging
    string literals, and makes it more explicit that they're the same in the
    C locale.
    
    libstdc++-v3/ChangeLog:
    
            * config/locale/dragonfly/time_members.cc
            (__timepunct<char>::_M_initialize_timepunc)
            (__timepunct<wchar_t>::_M_initialize_timepunc): Set
            _M_date_time_format for C locale. Set %Ex formats to the same
            values as the %x formats.
            * config/locale/generic/time_members.cc: Likewise.
            * config/locale/gnu/time_members.cc: Likewise.
            * testsuite/22_locale/time_get/get/char/5.cc: New test.
            * testsuite/22_locale/time_get/get/wchar_t/5.cc: New test.
    
    (cherry picked from commit c534e37faccf481afa9bc28f0605ca0ec3846c89)

Diff:
---
 .../config/locale/dragonfly/time_members.cc        | 16 +++++-----
 libstdc++-v3/config/locale/generic/time_members.cc |  8 ++---
 libstdc++-v3/config/locale/gnu/time_members.cc     | 16 +++++-----
 .../testsuite/22_locale/time_get/get/char/5.cc     | 37 ++++++++++++++++++++++
 .../testsuite/22_locale/time_get/get/wchar_t/5.cc  | 37 ++++++++++++++++++++++
 5 files changed, 94 insertions(+), 20 deletions(-)

diff --git a/libstdc++-v3/config/locale/dragonfly/time_members.cc 
b/libstdc++-v3/config/locale/dragonfly/time_members.cc
index 1dc83a6af6f3..88a0341d55ff 100644
--- a/libstdc++-v3/config/locale/dragonfly/time_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/time_members.cc
@@ -67,11 +67,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          _M_c_locale_timepunct = _S_get_c_locale();
 
          _M_data->_M_date_format = "%m/%d/%y";
-         _M_data->_M_date_era_format = "%m/%d/%y";
+         _M_data->_M_date_era_format = _M_data->_M_date_format;
          _M_data->_M_time_format = "%H:%M:%S";
-         _M_data->_M_time_era_format = "%H:%M:%S";
-         _M_data->_M_date_time_format = "";
-         _M_data->_M_date_time_era_format = "";
+         _M_data->_M_time_era_format = _M_data->_M_time_format;
+         _M_data->_M_date_time_format = "%a %b %e %T %Y";
+         _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
          _M_data->_M_am = "AM";
          _M_data->_M_pm = "PM";
          _M_data->_M_am_pm_format = "%I:%M:%S %p";
@@ -224,11 +224,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          _M_c_locale_timepunct = _S_get_c_locale();
 
          _M_data->_M_date_format = L"%m/%d/%y";
-         _M_data->_M_date_era_format = L"%m/%d/%y";
+         _M_data->_M_date_era_format = _M_data->_M_date_format;
          _M_data->_M_time_format = L"%H:%M:%S";
-         _M_data->_M_time_era_format = L"%H:%M:%S";
-         _M_data->_M_date_time_format = L"";
-         _M_data->_M_date_time_era_format = L"";
+         _M_data->_M_time_era_format = _M_data->_M_time_format;
+         _M_data->_M_date_time_format = L"%a %b %e %T %Y";
+         _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
          _M_data->_M_am = L"AM";
          _M_data->_M_pm = L"PM";
          _M_data->_M_am_pm_format = L"%I:%M:%S %p";
diff --git a/libstdc++-v3/config/locale/generic/time_members.cc 
b/libstdc++-v3/config/locale/generic/time_members.cc
index 369e1de4a972..03a4ecbc31a3 100644
--- a/libstdc++-v3/config/locale/generic/time_members.cc
+++ b/libstdc++-v3/config/locale/generic/time_members.cc
@@ -65,11 +65,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        _M_data = new __timepunct_cache<char>;
 
       _M_data->_M_date_format = "%m/%d/%y";
-      _M_data->_M_date_era_format = "%m/%d/%y";
+      _M_data->_M_date_era_format = _M_data->_M_date_format;
       _M_data->_M_time_format = "%H:%M:%S";
-      _M_data->_M_time_era_format = "%H:%M:%S";
-      _M_data->_M_date_time_format = "";
-      _M_data->_M_date_time_era_format = "";
+      _M_data->_M_time_era_format = _M_data->_M_time_format;
+      _M_data->_M_date_time_format = "%a %b %e %T %Y";
+      _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
       _M_data->_M_am = "AM";
       _M_data->_M_pm = "PM";
       _M_data->_M_am_pm_format = "%I:%M:%S %p";
diff --git a/libstdc++-v3/config/locale/gnu/time_members.cc 
b/libstdc++-v3/config/locale/gnu/time_members.cc
index 2d1ebdb33c0f..404451bedf6d 100644
--- a/libstdc++-v3/config/locale/gnu/time_members.cc
+++ b/libstdc++-v3/config/locale/gnu/time_members.cc
@@ -73,11 +73,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          _M_c_locale_timepunct = _S_get_c_locale();
 
          _M_data->_M_date_format = "%m/%d/%y";
-         _M_data->_M_date_era_format = "%m/%d/%y";
+         _M_data->_M_date_era_format = _M_data->_M_date_format;
          _M_data->_M_time_format = "%H:%M:%S";
-         _M_data->_M_time_era_format = "%H:%M:%S";
-         _M_data->_M_date_time_format = "";
-         _M_data->_M_date_time_era_format = "";
+         _M_data->_M_time_era_format = _M_data->_M_time_format;
+         _M_data->_M_date_time_format = "%a %b %e %T %Y";
+         _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
          _M_data->_M_am = "AM";
          _M_data->_M_pm = "PM";
          _M_data->_M_am_pm_format = "%I:%M:%S %p";
@@ -229,11 +229,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          _M_c_locale_timepunct = _S_get_c_locale();
 
          _M_data->_M_date_format = L"%m/%d/%y";
-         _M_data->_M_date_era_format = L"%m/%d/%y";
+         _M_data->_M_date_era_format = _M_data->_M_date_format;
          _M_data->_M_time_format = L"%H:%M:%S";
-         _M_data->_M_time_era_format = L"%H:%M:%S";
-         _M_data->_M_date_time_format = L"";
-         _M_data->_M_date_time_era_format = L"";
+         _M_data->_M_time_era_format = _M_data->_M_time_format;
+         _M_data->_M_date_time_format = L"%a %b %e %T %Y";
+         _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
          _M_data->_M_am = L"AM";
          _M_data->_M_pm = L"PM";
          _M_data->_M_am_pm_format = L"%I:%M:%S %p";
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/char/5.cc 
b/libstdc++-v3/testsuite/22_locale/time_get/get/char/5.cc
new file mode 100644
index 000000000000..61fc329cf3c9
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/time_get/get/char/5.cc
@@ -0,0 +1,37 @@
+// { dg-do run { target c++11} }
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  using Facet = std::time_get<char>;
+  const Facet& fac = std::use_facet<Facet>(std::locale::classic());
+  std::istringstream ss("Fri Jul 5 14:58:21 2019");
+  std::ios::iostate err = std::ios::goodbit;
+  std::tm tm = {};
+  fac.get(ss, Facet::iter_type(), ss, err, &tm, 'c');
+  VERIFY( err == std::ios::eofbit );
+  VERIFY( tm.tm_year == 119 );
+  VERIFY( tm.tm_mon == 6 );
+  VERIFY( tm.tm_mday == 5 );
+  VERIFY( tm.tm_wday == 5 );
+  VERIFY( tm.tm_hour == 14 );
+  VERIFY( tm.tm_min == 58 );
+  VERIFY( tm.tm_sec == 21 );
+  ss.clear();
+  ss.seekg(0);
+  ss.str(ss.str() + " non-whitespace after the datetime");
+  err = std::ios::goodbit;
+  tm = std::tm();
+  fac.get(ss, Facet::iter_type(), ss, err, &tm, 'c', 'E');
+  VERIFY( err == std::ios::goodbit );
+  VERIFY( tm.tm_year == 119 );
+  VERIFY( tm.tm_mon == 6 );
+  VERIFY( tm.tm_mday == 5 );
+  VERIFY( tm.tm_wday == 5 );
+  VERIFY( tm.tm_hour == 14 );
+  VERIFY( tm.tm_min == 58 );
+  VERIFY( tm.tm_sec == 21 );
+}
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/5.cc 
b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/5.cc
new file mode 100644
index 000000000000..5f350b043d9e
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/5.cc
@@ -0,0 +1,37 @@
+// { dg-do run { target c++11} }
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  using Facet = std::time_get<wchar_t>;
+  const Facet& fac = std::use_facet<Facet>(std::locale::classic());
+  std::wistringstream ss(L"Fri Jul 5 14:58:21 2019");
+  std::ios::iostate err = std::ios::goodbit;
+  std::tm tm = {};
+  fac.get(ss, Facet::iter_type(), ss, err, &tm, 'c');
+  VERIFY( err == std::ios::eofbit );
+  VERIFY( tm.tm_year == 119 );
+  VERIFY( tm.tm_mon == 6 );
+  VERIFY( tm.tm_mday == 5 );
+  VERIFY( tm.tm_wday == 5 );
+  VERIFY( tm.tm_hour == 14 );
+  VERIFY( tm.tm_min == 58 );
+  VERIFY( tm.tm_sec == 21 );
+  ss.clear();
+  ss.seekg(0);
+  ss.str(ss.str() + L" non-whitespace after the datetime");
+  err = std::ios::goodbit;
+  tm = std::tm();
+  fac.get(ss, Facet::iter_type(), ss, err, &tm, 'c', 'E');
+  VERIFY( err == std::ios::goodbit );
+  VERIFY( tm.tm_year == 119 );
+  VERIFY( tm.tm_mon == 6 );
+  VERIFY( tm.tm_mday == 5 );
+  VERIFY( tm.tm_wday == 5 );
+  VERIFY( tm.tm_hour == 14 );
+  VERIFY( tm.tm_min == 58 );
+  VERIFY( tm.tm_sec == 21 );
+}

Reply via email to