summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/include/bits/locale_facets_nonio.tcc216
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_get/get/char/3.cc356
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/3.cc356
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_get/get_date/char/12791.cc4
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_get/get_date/wchar_t/12791.cc4
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_get/get_time/char/2.cc2
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_get/get_time/char/5.cc2
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_get/get_time/wchar_t/2.cc2
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_get/get_time/wchar_t/5.cc2
9 files changed, 860 insertions, 84 deletions
diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
index 51c23d8003a..3456ee1dd6a 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
@@ -684,7 +684,7 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
time_get<_CharT, _InIter>::do_date_order() const
{ return time_base::no_order; }
- // Expand a strftime format string and parse it. E.g., do_get_date() may
+ // Expand a strptime format string and parse it. E.g., do_get_date() may
// pass %m/%d/%Y => extracted characters.
template<typename _CharT, typename _InIter>
_InIter
@@ -714,41 +714,27 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
const char* __cs;
_CharT __wcs[10];
case 'a':
- // Abbreviated weekday name [tm_wday]
- const char_type* __days1[7];
- __tp._M_days_abbreviated(__days1);
- __beg = _M_extract_name(__beg, __end, __mem, __days1,
- 7, __io, __tmperr);
- if (!__tmperr)
- __tm->tm_wday = __mem;
- break;
case 'A':
- // Weekday name [tm_wday].
- const char_type* __days2[7];
- __tp._M_days(__days2);
- __beg = _M_extract_name(__beg, __end, __mem, __days2,
- 7, __io, __tmperr);
+ // Weekday name (possibly abbreviated) [tm_wday]
+ const char_type* __days[14];
+ __tp._M_days(&__days[0]);
+ __tp._M_days_abbreviated(&__days[7]);
+ __beg = _M_extract_name(__beg, __end, __mem, __days,
+ 14, __io, __tmperr);
if (!__tmperr)
- __tm->tm_wday = __mem;
+ __tm->tm_wday = __mem % 7;
break;
case 'h':
case 'b':
- // Abbreviated month name [tm_mon]
- const char_type* __months1[12];
- __tp._M_months_abbreviated(__months1);
- __beg = _M_extract_name(__beg, __end, __mem,
- __months1, 12, __io, __tmperr);
- if (!__tmperr)
- __tm->tm_mon = __mem;
- break;
case 'B':
- // Month name [tm_mon].
- const char_type* __months2[12];
- __tp._M_months(__months2);
+ // Month name (possibly abbreviated) [tm_mon]
+ const char_type* __months[24];
+ __tp._M_months(&__months[0]);
+ __tp._M_months_abbreviated(&__months[12]);
__beg = _M_extract_name(__beg, __end, __mem,
- __months2, 12, __io, __tmperr);
+ __months, 24, __io, __tmperr);
if (!__tmperr)
- __tm->tm_mon = __mem;
+ __tm->tm_mon = __mem % 12;
break;
case 'c':
// Default time and date representation.
@@ -758,21 +744,12 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
__tm, __dt[0]);
break;
case 'd':
- // Day [01, 31]. [tm_mday]
- __beg = _M_extract_num(__beg, __end, __mem, 1, 31, 2,
- __io, __tmperr);
- if (!__tmperr)
- __tm->tm_mday = __mem;
- break;
case 'e':
- // Day [1, 31], with single digits preceded by
- // space. [tm_mday]
+ // Day [1, 31]. [tm_mday]
if (__ctype.is(ctype_base::space, *__beg))
- __beg = _M_extract_num(++__beg, __end, __mem, 1, 9,
- 1, __io, __tmperr);
- else
- __beg = _M_extract_num(__beg, __end, __mem, 10, 31,
- 2, __io, __tmperr);
+ ++__beg;
+ __beg = _M_extract_num(__beg, __end, __mem, 1, 31, 2,
+ __io, __tmperr);
if (!__tmperr)
__tm->tm_mday = __mem;
break;
@@ -795,7 +772,7 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
__beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2,
__io, __tmperr);
if (!__tmperr)
- __tm->tm_hour = __mem;
+ __tm->tm_hour = __mem % 12;
break;
case 'm':
// Month [01, 12]. [tm_mon]
@@ -812,10 +789,22 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
__tm->tm_min = __mem;
break;
case 'n':
- if (__ctype.narrow(*__beg, 0) == '\n')
+ case 't':
+ while (__beg != __end
+ && __ctype.is(ctype_base::space, *__beg))
++__beg;
- else
- __tmperr |= ios_base::failbit;
+ break;
+ case 'p':
+ // Locale's a.m. or p.m.
+ const char_type* __ampm[2];
+ __tp._M_am_pm(&__ampm[0]);
+ if (!__ampm[0][0] || !__ampm[1][0])
+ break;
+ __beg = _M_extract_name(__beg, __end, __mem, __ampm,
+ 2, __io, __tmperr);
+ // FIXME: This only works if %I comes before %p.
+ if (!__tmperr && __mem)
+ __tm->tm_hour += 12;
break;
case 'R':
// Equivalent to (%H:%M).
@@ -836,12 +825,6 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
if (!__tmperr)
__tm->tm_sec = __mem;
break;
- case 't':
- if (__ctype.narrow(*__beg, 0) == '\t')
- ++__beg;
- else
- __tmperr |= ios_base::failbit;
- break;
case 'T':
// Equivalent to (%H:%M:%S).
__cs = "%H:%M:%S";
@@ -899,11 +882,24 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
else
__tmperr |= ios_base::failbit;
break;
+ case '%':
+ if (*__beg == __ctype.widen('%'))
+ ++__beg;
+ else
+ __tmperr |= ios_base::failbit;
+ break;
default:
// Not recognized.
__tmperr |= ios_base::failbit;
}
}
+ else if (__ctype.is(ctype_base::space, __format[__i]))
+ {
+ // Skip any whitespace.
+ while (__beg != __end
+ && __ctype.is(ctype_base::space, *__beg))
+ ++__beg;
+ }
else
{
// Verify format and input match, extract and discard.
@@ -930,10 +926,6 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
const locale& __loc = __io._M_getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
- // As-is works for __len = 1, 2, 4, the values actually used.
- int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1);
-
- ++__min;
size_t __i = 0;
int __value = 0;
for (; __beg != __end && __i < __len; ++__beg, (void)++__i)
@@ -942,19 +934,20 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
if (__c >= '0' && __c <= '9')
{
__value = __value * 10 + (__c - '0');
- const int __valuec = __value * __mult;
- if (__valuec > __max || __valuec + __mult < __min)
+ if (__value > __max)
break;
- __mult /= 10;
}
else
break;
}
- if (__i == __len)
- __member = __value;
// Special encoding for do_get_year, 'y', and 'Y' above.
- else if (__len == 4 && __i == 2)
+ if (__len == 4 && __i == 2)
__member = __value - 100;
+ else if (__len == 4 && __i == 4)
+ __member = __value;
+ else if (__len == 2 && __i && __i <= 2
+ && __value >= __min && __value <= __max)
+ __member = __value;
else
__err |= ios_base::failbit;
@@ -962,7 +955,10 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
}
// Assumptions:
- // All elements in __names are unique.
+ // All elements in __names are unique, except if __indexlen is
+ // even __names in the first half could be the same as corresponding
+ // __names in the second half (May is abbreviated as May). Some __names
+ // elements could be prefixes of other __names elements.
template<typename _CharT, typename _InIter>
_InIter
time_get<_CharT, _InIter>::
@@ -974,12 +970,15 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
const locale& __loc = __io._M_getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
- int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int)
- * __indexlen));
+ size_t* __matches
+ = static_cast<size_t*>(__builtin_alloca(2 * sizeof(size_t)
+ * __indexlen));
+ size_t* __lengths = __matches + __indexlen;
size_t __nmatches = 0;
size_t __pos = 0;
bool __testvalid = true;
const char_type* __name;
+ bool __begupdated = false;
// Look for initial matches.
// NB: Some of the locale data is in the form of all lowercase
@@ -991,26 +990,88 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
if (__c == __names[__i1][0]
|| __c == __ctype.toupper(__names[__i1][0]))
- __matches[__nmatches++] = __i1;
+ {
+ __lengths[__nmatches]
+ = __traits_type::length(__names[__i1]);
+ __matches[__nmatches++] = __i1;
+ }
}
while (__nmatches > 1)
{
// Find smallest matching string.
- size_t __minlen = __traits_type::length(__names[__matches[0]]);
+ size_t __minlen = __lengths[0];
for (size_t __i2 = 1; __i2 < __nmatches; ++__i2)
- __minlen = std::min(__minlen,
- __traits_type::length(__names[__matches[__i2]]));
- ++__beg;
+ __minlen = std::min(__minlen, __lengths[__i2]);
++__pos;
+ ++__beg;
+ if (__pos == __minlen)
+ {
+ // If some match has remaining length of 0,
+ // need to decide if any match with remaining
+ // length non-zero matches the next character.
+ // If so, remove all matches with remaining length
+ // 0 from consideration, otherwise keep only matches
+ // with remaining length 0.
+ bool __match_longer = false;
+
+ if (__beg != __end)
+ for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
+ {
+ __name = __names[__matches[__i3]];
+ if (__lengths[__i3] > __pos && (__name[__pos] == *__beg))
+ {
+ __match_longer = true;
+ break;
+ }
+ }
+ for (size_t __i4 = 0; __i4 < __nmatches;)
+ if (__match_longer == (__lengths[__i4] == __pos))
+ {
+ __matches[__i4] = __matches[--__nmatches];
+ __lengths[__i4] = __lengths[__nmatches];
+ }
+ else
+ ++__i4;
+ if (__match_longer)
+ {
+ __minlen = __lengths[0];
+ for (size_t __i5 = 1; __i5 < __nmatches; ++__i5)
+ __minlen = std::min(__minlen, __lengths[__i5]);
+ }
+ else
+ {
+ // Deal with May being full as well as abbreviated month
+ // name. Pick the smaller index.
+ if (__nmatches == 2 && (__indexlen & 1) == 0)
+ {
+ if (__matches[0] < __indexlen / 2)
+ {
+ if (__matches[1] == __matches[0] + __indexlen / 2)
+ __nmatches = 1;
+ }
+ else if (__matches[1] == __matches[0] - __indexlen / 2)
+ {
+ __matches[0] = __matches[1];
+ __lengths[0] = __lengths[1];
+ __nmatches = 1;
+ }
+ }
+ __begupdated = true;
+ break;
+ }
+ }
if (__pos < __minlen && __beg != __end)
- for (size_t __i3 = 0; __i3 < __nmatches;)
+ for (size_t __i6 = 0; __i6 < __nmatches;)
{
- __name = __names[__matches[__i3]];
+ __name = __names[__matches[__i6]];
if (!(__name[__pos] == *__beg))
- __matches[__i3] = __matches[--__nmatches];
+ {
+ __matches[__i6] = __matches[--__nmatches];
+ __lengths[__i6] = __lengths[__nmatches];
+ }
else
- ++__i3;
+ ++__i6;
}
else
break;
@@ -1019,10 +1080,13 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
if (__nmatches == 1)
{
// Make sure found name is completely extracted.
- ++__beg;
- ++__pos;
+ if (!__begupdated)
+ {
+ ++__beg;
+ ++__pos;
+ }
__name = __names[__matches[0]];
- const size_t __len = __traits_type::length(__name);
+ const size_t __len = __lengths[0];
while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
++__beg, (void)++__pos;
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/char/3.cc b/libstdc++-v3/testsuite/22_locale/time_get/get/char/3.cc
new file mode 100644
index 00000000000..524c1c5a97f
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/time_get/get/char/3.cc
@@ -0,0 +1,356 @@
+// { 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;
+
+ // PR78714 tests
+ iss.str("Mon");
+ string format = "%a";
+ 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_wday == 1 );
+
+ iss.str("Tue ");
+ format = "%a";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret != end && *ret == ' ' );
+ VERIFY( time.tm_wday == 2 );
+
+ iss.str("Wednesday");
+ format = "%a";
+ 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_wday == 3 );
+
+ iss.str("Thu");
+ format = "%A";
+ 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_wday == 4 );
+
+ iss.str("Fri ");
+ format = "%A";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret != end && *ret == ' ' );
+ VERIFY( time.tm_wday == 5 );
+
+ iss.str("Saturday");
+ format = "%A";
+ 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_wday == 6 );
+
+ iss.str("Feb");
+ format = "%b";
+ 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_mon == 1 );
+
+ iss.str("Mar ");
+ format = "%b";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret != end && *ret == ' ' );
+ VERIFY( time.tm_mon == 2 );
+
+ iss.str("April");
+ format = "%b";
+ 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_mon == 3 );
+
+ iss.str("May");
+ format = "%B";
+ 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_mon == 4 );
+
+ iss.str("Jun ");
+ format = "%B";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret != end && *ret == ' ' );
+ VERIFY( time.tm_mon == 5 );
+
+ iss.str("July");
+ format = "%B";
+ 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_mon == 6 );
+
+ iss.str("Aug");
+ format = "%h";
+ 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_mon == 7 );
+
+ iss.str("May ");
+ format = "%h";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret != end && *ret == ' ' );
+ VERIFY( time.tm_mon == 4 );
+
+ iss.str("October");
+ format = "%h";
+ 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_mon == 9 );
+
+ // Other tests.
+ iss.str(" 1.");
+ format = "%d.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 1 );
+
+ iss.str("2.");
+ format = "%d.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 2 );
+
+ iss.str("03.");
+ format = "%d.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 3 );
+
+ iss.str("0.");
+ format = "%d.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit );
+ VERIFY( ret != end && *ret == '.' );
+
+ iss.str("32.");
+ format = "%d.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit );
+ VERIFY( ret != end && *ret == '2' );
+
+ iss.str(" 4.");
+ format = "%e.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 4 );
+
+ iss.str("5.");
+ format = "%e.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 5 );
+
+ iss.str("06.");
+ format = "%e.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 6 );
+
+ iss.str("0");
+ format = "%e";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit|ios_base::eofbit );
+ VERIFY( ret == end );
+
+ iss.str("35");
+ format = "%e";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit );
+ VERIFY( ret != end && *ret == '5' );
+
+ iss.str(" \t\t 02");
+ format = "%t%m";
+ 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_mon == 1 );
+
+ iss.str(" \t \t 03");
+ format = "%n%m";
+ 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_mon == 2 );
+
+ iss.str(" \t \t 4");
+ format = " %m";
+ 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_mon == 3 );
+
+ iss.str(" \t \t 5");
+ format = "\t%m";
+ 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_mon == 4 );
+
+ iss.str("12:00AM");
+ format = "%I:%M%p";
+ 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 == 0 );
+ VERIFY( time.tm_min == 0 );
+
+ iss.str("12:37AM");
+ format = "%I:%M%p";
+ 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 == 0 );
+ VERIFY( time.tm_min == 37 );
+
+ iss.str("01:25AM");
+ format = "%I:%M%p";
+ 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 == 1 );
+ VERIFY( time.tm_min == 25 );
+
+ iss.str("12:00PM");
+ format = "%I:%M%p";
+ 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 == 12 );
+ VERIFY( time.tm_min == 0 );
+
+ iss.str("12:42PM");
+ format = "%I:%M%p";
+ 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 == 12 );
+ VERIFY( time.tm_min == 42 );
+
+ iss.str("07:23PM");
+ format = "%I:%M%p";
+ 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 == 19 );
+ VERIFY( time.tm_min == 23 );
+
+ iss.str("17%20");
+ format = "%H%%%M";
+ 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 == 17 );
+ VERIFY( time.tm_min == 20 );
+
+ iss.str("24:30");
+ format = "%H:%M";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit );
+ VERIFY( ret != end && *ret == '4' );
+
+ // This one behaves differently from strptime, in a single
+ // pass scaning we can't go back.
+ iss.str("Novembur");
+ format = "%bembur";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit );
+ VERIFY( ret != end && *ret == 'u' );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/3.cc b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/3.cc
new file mode 100644
index 00000000000..cbc31445677
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/3.cc
@@ -0,0 +1,356 @@
+// { 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;
+
+ // PR78714 tests
+ iss.str(L"Mon");
+ wstring format = L"%a";
+ 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_wday == 1 );
+
+ iss.str(L"Tue L");
+ format = L"%a";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret != end && *ret == L' ' );
+ VERIFY( time.tm_wday == 2 );
+
+ iss.str(L"Wednesday");
+ format = L"%a";
+ 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_wday == 3 );
+
+ iss.str(L"Thu");
+ format = L"%A";
+ 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_wday == 4 );
+
+ iss.str(L"Fri L");
+ format = L"%A";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret != end && *ret == L' ' );
+ VERIFY( time.tm_wday == 5 );
+
+ iss.str(L"Saturday");
+ format = L"%A";
+ 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_wday == 6 );
+
+ iss.str(L"Feb");
+ format = L"%b";
+ 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_mon == 1 );
+
+ iss.str(L"Mar L");
+ format = L"%b";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret != end && *ret == L' ' );
+ VERIFY( time.tm_mon == 2 );
+
+ iss.str(L"April");
+ format = L"%b";
+ 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_mon == 3 );
+
+ iss.str(L"May");
+ format = L"%B";
+ 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_mon == 4 );
+
+ iss.str(L"Jun L");
+ format = L"%B";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret != end && *ret == L' ' );
+ VERIFY( time.tm_mon == 5 );
+
+ iss.str(L"July");
+ format = L"%B";
+ 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_mon == 6 );
+
+ iss.str(L"Aug");
+ format = L"%h";
+ 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_mon == 7 );
+
+ iss.str(L"May L");
+ format = L"%h";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret != end && *ret == L' ' );
+ VERIFY( time.tm_mon == 4 );
+
+ iss.str(L"October");
+ format = L"%h";
+ 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_mon == 9 );
+
+ // Other tests.
+ iss.str(L" 1.");
+ format = L"%d.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 1 );
+
+ iss.str(L"2.");
+ format = L"%d.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 2 );
+
+ iss.str(L"03.");
+ format = L"%d.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 3 );
+
+ iss.str(L"0.");
+ format = L"%d.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit );
+ VERIFY( ret != end && *ret == L'.' );
+
+ iss.str(L"32.");
+ format = L"%d.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit );
+ VERIFY( ret != end && *ret == L'2' );
+
+ iss.str(L" 4.");
+ format = L"%e.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 4 );
+
+ iss.str(L"5.");
+ format = L"%e.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 5 );
+
+ iss.str(L"06.");
+ format = L"%e.";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( ret == end );
+ VERIFY( time.tm_mday == 6 );
+
+ iss.str(L"0");
+ format = L"%e";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit|ios_base::eofbit );
+ VERIFY( ret == end );
+
+ iss.str(L"35");
+ format = L"%e";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit );
+ VERIFY( ret != end && *ret == L'5' );
+
+ iss.str(L" \t\t 02");
+ format = L"%t%m";
+ 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_mon == 1 );
+
+ iss.str(L" \t \t 03");
+ format = L"%n%m";
+ 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_mon == 2 );
+
+ iss.str(L" \t \t 4");
+ format = L" %m";
+ 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_mon == 3 );
+
+ iss.str(L" \t \t 5");
+ format = L"\t%m";
+ 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_mon == 4 );
+
+ iss.str(L"12:00AM");
+ format = L"%I:%M%p";
+ 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 == 0 );
+ VERIFY( time.tm_min == 0 );
+
+ iss.str(L"12:37AM");
+ format = L"%I:%M%p";
+ 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 == 0 );
+ VERIFY( time.tm_min == 37 );
+
+ iss.str(L"01:25AM");
+ format = L"%I:%M%p";
+ 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 == 1 );
+ VERIFY( time.tm_min == 25 );
+
+ iss.str(L"12:00PM");
+ format = L"%I:%M%p";
+ 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 == 12 );
+ VERIFY( time.tm_min == 0 );
+
+ iss.str(L"12:42PM");
+ format = L"%I:%M%p";
+ 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 == 12 );
+ VERIFY( time.tm_min == 42 );
+
+ iss.str(L"07:23PM");
+ format = L"%I:%M%p";
+ 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 == 19 );
+ VERIFY( time.tm_min == 23 );
+
+ iss.str(L"17%20");
+ format = L"%H%%%M";
+ 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 == 17 );
+ VERIFY( time.tm_min == 20 );
+
+ iss.str(L"24:30");
+ format = L"%H:%M";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit );
+ VERIFY( ret != end && *ret == L'4' );
+
+ // This one behaves differently from strptime, in a single
+ // pass scaning we can't go back.
+ iss.str(L"Novembur");
+ format = L"%bembur";
+ ret = tget.get(iter(iss), end, iss, err, &time,
+ format.data(), format.data()+format.size());
+ VERIFY( err == ios_base::failbit );
+ VERIFY( ret != end && *ret == L'u' );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_date/char/12791.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_date/char/12791.cc
index 07b655c0fdc..958a8f196bb 100644
--- a/libstdc++-v3/testsuite/22_locale/time_get/get_date/char/12791.cc
+++ b/libstdc++-v3/testsuite/22_locale/time_get/get_date/char/12791.cc
@@ -39,14 +39,14 @@ void test01()
const ios_base::iostate good = ios_base::goodbit;
ios_base::iostate errorstate = good;
- iss.str("60/04/71");
+ iss.str("62/04/71");
iterator_type is_it01(iss);
tm time01;
errorstate = good;
iterator_type ret01 = tim_get.get_date(is_it01, end, iss, errorstate,
&time01);
VERIFY( errorstate == ios_base::failbit );
- VERIFY( *ret01 == '6' );
+ VERIFY( *ret01 == '2' );
iss.str("04/38/71");
iterator_type is_it02(iss);
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_date/wchar_t/12791.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_date/wchar_t/12791.cc
index a33d695825d..0cf8f67ccd2 100644
--- a/libstdc++-v3/testsuite/22_locale/time_get/get_date/wchar_t/12791.cc
+++ b/libstdc++-v3/testsuite/22_locale/time_get/get_date/wchar_t/12791.cc
@@ -40,14 +40,14 @@ void test01()
const ios_base::iostate good = ios_base::goodbit;
ios_base::iostate errorstate = good;
- iss.str(L"60/04/71");
+ iss.str(L"62/04/71");
iterator_type is_it01(iss);
tm time01;
errorstate = good;
iterator_type ret01 = tim_get.get_date(is_it01, end, iss, errorstate,
&time01);
VERIFY( errorstate == ios_base::failbit );
- VERIFY( *ret01 == L'6' );
+ VERIFY( *ret01 == L'2' );
iss.str(L"04/38/71");
iterator_type is_it02(iss);
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_time/char/2.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_time/char/2.cc
index 79f921d1cf6..a847748dc27 100644
--- a/libstdc++-v3/testsuite/22_locale/time_get/get_time/char/2.cc
+++ b/libstdc++-v3/testsuite/22_locale/time_get/get_time/char/2.cc
@@ -48,7 +48,7 @@ void test02()
// inspection of named locales, en_HK
iss.imbue(loc_hk);
- iss.str("12:00:00 PST");
+ iss.str("12:00:00 PM PST");
// Hong Kong in California! Well, they have Paris in Vegas... this
// is all a little disney-esque anyway. Besides, you can get decent
// Dim Sum in San Francisco.
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_time/char/5.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_time/char/5.cc
index c7777962b46..a9bb79ce453 100644
--- a/libstdc++-v3/testsuite/22_locale/time_get/get_time/char/5.cc
+++ b/libstdc++-v3/testsuite/22_locale/time_get/get_time/char/5.cc
@@ -52,7 +52,7 @@ void test01()
VERIFY( err == (failbit | eofbit) );
VERIFY( tm0.tm_sec == 0 );
VERIFY( tm0.tm_min == 0 );
- VERIFY( tm0.tm_hour == 0 );
+ VERIFY( tm0.tm_hour == 1 );
const string str1 = "12:00:00 ";
iter_type end1 = tg.get_time(str1.begin(), str1.end(), iss, err, &tm1);
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_time/wchar_t/2.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_time/wchar_t/2.cc
index 6c3f5c2215d..b5d61e1afdb 100644
--- a/libstdc++-v3/testsuite/22_locale/time_get/get_time/wchar_t/2.cc
+++ b/libstdc++-v3/testsuite/22_locale/time_get/get_time/wchar_t/2.cc
@@ -48,7 +48,7 @@ void test02()
// inspection of named locales, en_HK
iss.imbue(loc_hk);
- iss.str(L"12:00:00 PST");
+ iss.str(L"12:00:00 PM PST");
// Hong Kong in California! Well, they have Paris in Vegas... this
// is all a little disney-esque anyway. Besides, you can get decent
// Dim Sum in San Francisco.
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_time/wchar_t/5.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_time/wchar_t/5.cc
index 8fda7fb28ef..db25046d33d 100644
--- a/libstdc++-v3/testsuite/22_locale/time_get/get_time/wchar_t/5.cc
+++ b/libstdc++-v3/testsuite/22_locale/time_get/get_time/wchar_t/5.cc
@@ -52,7 +52,7 @@ void test01()
VERIFY( err == (failbit | eofbit) );
VERIFY( tm0.tm_sec == 0 );
VERIFY( tm0.tm_min == 0 );
- VERIFY( tm0.tm_hour == 0 );
+ VERIFY( tm0.tm_hour == 1 );
const wstring str1 = L"12:00:00 ";
iter_type end1 = tg.get_time(str1.begin(), str1.end(), iss, err, &tm1);