]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Populate std::time_get::get's %c format for C locale
authorJonathan Wakely <jwakely@redhat.com>
Tue, 24 Sep 2024 22:20:56 +0000 (23:20 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 2 Oct 2024 10:36:17 +0000 (11:36 +0100)
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.

libstdc++-v3/config/locale/dragonfly/time_members.cc
libstdc++-v3/config/locale/generic/time_members.cc
libstdc++-v3/config/locale/gnu/time_members.cc
libstdc++-v3/testsuite/22_locale/time_get/get/char/5.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/5.cc [new file with mode: 0644]

index 0c96928135ebbe5bc763dfe8c4ee08c6b24745a6..069b2ddd26bb60c2a54db17d8bddc4b4b17fe0b7 100644 (file)
@@ -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";
index 68395820fefab47b5f5522b99b6f786219667561..6619f0ca881a6c1f948d96e858addfc8db4bf1e9 100644 (file)
@@ -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";
index 1e3b87488faece0278c95ca6ec88f2f3d7f902f8..88c8ab700809350a8a841603eab934bb74e9c4db 100644 (file)
@@ -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 (file)
index 0000000..61fc329
--- /dev/null
@@ -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 (file)
index 0000000..5f350b0
--- /dev/null
@@ -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 );
+}