libstdc++: Add std::time_get %r support [PR71367]
This incremental patch adds std::time_get %r support (%p was added already in the previous patch). The _M_am_fm_format method previously in the header unfortunately had wrong arguments and so was useless, so the largest complication in this patch is exporting a new symbol in the right symbol version. 2021-12-10 Jakub Jelinek <jakub@redhat.com> PR libstdc++/71367 * config/locale/dragonfly/time_members.cc (_M_initialize_timepunct): Initialize "C" _M_am_pm_format to %I:%M:%S %p rather than empty string. * config/locale/gnu/time_members.cc (_M_initialize_timepunct): Likewise. * config/locale/generic/time_members.cc (_M_initialize_timepunct): Likewise. * include/bits/locale_facets_nonio.h (_M_am_pm_format): New method. * include/bits/locale_facets_nonio.tcc (_M_extract_via_format): Handle %r. * config/abi/pre/gnu.ver (GLIBCXX_3.4.30): Export _M_am_pm_format with const _CharT** argument, ensure it isn't exported in GLIBCXX_3.4. * testsuite/22_locale/time_get/get/char/71367.cc: New test. * testsuite/22_locale/time_get/get/wchar_t/71367.cc: New test.
This commit is contained in:
parent
c82e492616
commit
982a2c9b78
|
@ -185,7 +185,13 @@ GLIBCXX_3.4 {
|
|||
std::_List_node_base::unhook*;
|
||||
std::_List_node_base::reverse*;
|
||||
std::_List_node_base::transfer*;
|
||||
std::__timepunct*;
|
||||
# std::__timepunct*;
|
||||
std::__timepunct?char?::[^_]*;
|
||||
std::__timepunct?char?::_[^M]*;
|
||||
std::__timepunct?char?::_M_[^a]*;
|
||||
std::__timepunct?wchar_t?::[^_]*;
|
||||
std::__timepunct?wchar_t?::_[^M]*;
|
||||
std::__timepunct?wchar_t?::_M_[^a]*;
|
||||
# std::__numeric_limits_base*;
|
||||
std::__num_base::_S_format_float*;
|
||||
std::__num_base::_S_format_int*;
|
||||
|
@ -684,6 +690,10 @@ GLIBCXX_3.4 {
|
|||
# std::__convert_to_v
|
||||
_ZSt14__convert_to_vI[^gU]*;
|
||||
|
||||
# std::__timepunct
|
||||
_ZNKSt11__timepunctI[cw]E8_M_am_pmEPPK[cw];
|
||||
_ZNKSt11__timepunctI[cw]E15_M_am_pm_formatEPK[cw];
|
||||
|
||||
# __gnu_cxx::stdio_sync_filebuf
|
||||
_ZTVN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EEE;
|
||||
|
||||
|
@ -2411,6 +2421,9 @@ GLIBCXX_3.4.30 {
|
|||
_ZNSt18condition_variable4waitERSt11unique_lockISt5mutexE;
|
||||
#endif
|
||||
|
||||
# std::__timepunct<char>::_M_am_pm_format(const char**)
|
||||
_ZNKSt11__timepunctI[cw]E15_M_am_pm_formatEPPK[cw];
|
||||
|
||||
} GLIBCXX_3.4.29;
|
||||
|
||||
# Symbols in the support library (libsupc++) have their own tag.
|
||||
|
|
|
@ -74,7 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_M_data->_M_date_time_era_format = "";
|
||||
_M_data->_M_am = "AM";
|
||||
_M_data->_M_pm = "PM";
|
||||
_M_data->_M_am_pm_format = "";
|
||||
_M_data->_M_am_pm_format = "%I:%M:%S %p";
|
||||
|
||||
// Day names, starting with "C"'s Sunday.
|
||||
_M_data->_M_day1 = "Sunday";
|
||||
|
@ -231,7 +231,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_M_data->_M_date_time_era_format = L"";
|
||||
_M_data->_M_am = L"AM";
|
||||
_M_data->_M_pm = L"PM";
|
||||
_M_data->_M_am_pm_format = L"";
|
||||
_M_data->_M_am_pm_format = L"%I:%M:%S %p";
|
||||
|
||||
// Day names, starting with "C"'s Sunday.
|
||||
_M_data->_M_day1 = L"Sunday";
|
||||
|
|
|
@ -72,7 +72,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_M_data->_M_date_time_era_format = "";
|
||||
_M_data->_M_am = "AM";
|
||||
_M_data->_M_pm = "PM";
|
||||
_M_data->_M_am_pm_format = "";
|
||||
_M_data->_M_am_pm_format = "%I:%M:%S %p";
|
||||
|
||||
// Day names, starting with "C"'s Sunday.
|
||||
_M_data->_M_day1 = "Sunday";
|
||||
|
@ -157,7 +157,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_M_data->_M_date_time_era_format = L"";
|
||||
_M_data->_M_am = L"AM";
|
||||
_M_data->_M_pm = L"PM";
|
||||
_M_data->_M_am_pm_format = L"";
|
||||
_M_data->_M_am_pm_format = L"%I:%M:%S %p";
|
||||
|
||||
// Day names, starting with "C"'s Sunday.
|
||||
_M_data->_M_day1 = L"Sunday";
|
||||
|
|
|
@ -80,7 +80,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_M_data->_M_date_time_era_format = "";
|
||||
_M_data->_M_am = "AM";
|
||||
_M_data->_M_pm = "PM";
|
||||
_M_data->_M_am_pm_format = "";
|
||||
_M_data->_M_am_pm_format = "%I:%M:%S %p";
|
||||
|
||||
// Day names, starting with "C"'s Sunday.
|
||||
_M_data->_M_day1 = "Sunday";
|
||||
|
@ -236,7 +236,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_M_data->_M_date_time_era_format = L"";
|
||||
_M_data->_M_am = L"AM";
|
||||
_M_data->_M_pm = L"PM";
|
||||
_M_data->_M_am_pm_format = L"";
|
||||
_M_data->_M_am_pm_format = L"%I:%M:%S %p";
|
||||
|
||||
// Day names, starting with "C"'s Sunday.
|
||||
_M_data->_M_day1 = L"Sunday";
|
||||
|
|
|
@ -242,6 +242,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
{ /* Kept for ABI compatibility, see PR65927 */ }
|
||||
#endif
|
||||
|
||||
void
|
||||
_M_am_pm_format(const _CharT** __ampm_format) const
|
||||
{
|
||||
__ampm_format[0] = _M_data->_M_am_pm_format;
|
||||
}
|
||||
|
||||
void
|
||||
_M_am_pm(const _CharT** __ampm) const
|
||||
{
|
||||
|
|
|
@ -806,6 +806,13 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
|
|||
if (!__tmperr && __mem)
|
||||
__tm->tm_hour += 12;
|
||||
break;
|
||||
case 'r':
|
||||
// Locale's 12-hour clock time format (in C %I:%M:%S %p).
|
||||
const char_type* __ampm_format;
|
||||
__tp._M_am_pm_format(&__ampm_format);
|
||||
__beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
|
||||
__tm, __ampm_format);
|
||||
break;
|
||||
case 'R':
|
||||
// Equivalent to (%H:%M).
|
||||
__cs = "%H:%M";
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
// { dg-do run { target c++11 } }
|
||||
|
||||
// Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
locale loc_c = locale::classic();
|
||||
|
||||
istringstream iss;
|
||||
iss.imbue(loc_c);
|
||||
const time_get<char>& tget = use_facet<time_get<char>>(iss.getloc());
|
||||
typedef istreambuf_iterator<char> iter;
|
||||
const iter end;
|
||||
|
||||
tm time;
|
||||
ios_base::iostate err = ios_base::badbit;
|
||||
|
||||
iss.str("01:38:12 PM");
|
||||
string format = "%I:%M:%S %p";
|
||||
auto ret = tget.get(iter(iss), end, iss, err, &time,
|
||||
format.data(), format.data()+format.size());
|
||||
VERIFY( err == ios_base::eofbit );
|
||||
VERIFY( ret == end );
|
||||
VERIFY( time.tm_hour == 13 );
|
||||
VERIFY( time.tm_min == 38 );
|
||||
VERIFY( time.tm_sec == 12 );
|
||||
|
||||
iss.str("11:17:42 PM");
|
||||
format = "%r";
|
||||
ret = tget.get(iter(iss), end, iss, err, &time,
|
||||
format.data(), format.data()+format.size());
|
||||
VERIFY( err == ios_base::eofbit );
|
||||
VERIFY( ret == end );
|
||||
VERIFY( time.tm_hour == 23 );
|
||||
VERIFY( time.tm_min == 17 );
|
||||
VERIFY( time.tm_sec == 42 );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// { dg-do run { target c++11 } }
|
||||
|
||||
// Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
locale loc_c = locale::classic();
|
||||
|
||||
wistringstream iss;
|
||||
iss.imbue(loc_c);
|
||||
const time_get<wchar_t>& tget = use_facet<time_get<wchar_t>>(iss.getloc());
|
||||
typedef istreambuf_iterator<wchar_t> iter;
|
||||
const iter end;
|
||||
|
||||
tm time;
|
||||
ios_base::iostate err = ios_base::badbit;
|
||||
|
||||
iss.str(L"01:38:12 PM");
|
||||
wstring format = L"%I:%M:%S %p";
|
||||
auto ret = tget.get(iter(iss), end, iss, err, &time,
|
||||
format.data(), format.data()+format.size());
|
||||
VERIFY( err == ios_base::eofbit );
|
||||
VERIFY( ret == end );
|
||||
VERIFY( time.tm_hour == 13 );
|
||||
VERIFY( time.tm_min == 38 );
|
||||
VERIFY( time.tm_sec == 12 );
|
||||
|
||||
iss.str(L"11:17:42 PM");
|
||||
format = L"%r";
|
||||
ret = tget.get(iter(iss), end, iss, err, &time,
|
||||
format.data(), format.data()+format.size());
|
||||
VERIFY( err == ios_base::eofbit );
|
||||
VERIFY( ret == end );
|
||||
VERIFY( time.tm_hour == 23 );
|
||||
VERIFY( time.tm_min == 17 );
|
||||
VERIFY( time.tm_sec == 42 );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue