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.
This commit is contained in:
Jonathan Wakely 2024-09-24 23:20:56 +01:00 committed by Jonathan Wakely
parent 5cf26f2569
commit c534e37fac
No known key found for this signature in database
5 changed files with 94 additions and 20 deletions

View 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";

View 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";

View 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";

View File

@ -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 );
}

View File

@ -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 );
}