re PR libstdc++/12750 (time_get::_M_extract_via_format doesn't deal with 'e')

2003-10-27  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/12750
	* include/bits/locale_facets.tcc
	(time_get::_M_extract_via_format): Deal with code 'e'.
	* testsuite/22_locale/time_get/get_date/char/12750.cc: New.
	* testsuite/22_locale/time_get/get_date/wchar_t/12750.cc: Ditto.

	* include/bits/locale_facets.tcc
	(time_get::_M_extract_via_format): Tweak to absolutely avoid
	dereferencing end iterators.

	* include/bits/locale_facets.h (__verify_grouping):
	Const-ify second parameter.
	* include/bits/locale_facets.tcc (__verify_grouping): Ditto.
	* src/locale-inst.cc (__verify_grouping): Ditto.

2003-10-27  Paolo Carlini  <pcarlini@suse.de>

	* include/bits/locale_facets.tcc (num_get::_M_extract_float):
	Various things: 1- Avoid absolutely end iterator dereferences;
	2- Improve performance-wise the code skipping leading zeros;
	3- Fix two bugs wrt early bail out in case of parsing errors
	(see testcases); 4- General clean up.
	(num_get::_M_extract_int): Likewise, except 3-. Additionally,
	use __builtin_expect to favor base 10 inputs.
	* testsuite/22_locale/num_get/get/char/7.cc: New.
	* testsuite/22_locale/num_get/get/wchar_t/7.cc: Ditto.

From-SVN: r72987
This commit is contained in:
Paolo Carlini 2003-10-27 16:21:14 +00:00 committed by Paolo Carlini
parent 436d77152e
commit f20d2b7871
8 changed files with 402 additions and 83 deletions

View File

@ -1,3 +1,32 @@
2003-10-27 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/12750
* include/bits/locale_facets.tcc
(time_get::_M_extract_via_format): Deal with code 'e'.
* testsuite/22_locale/time_get/get_date/char/12750.cc: New.
* testsuite/22_locale/time_get/get_date/wchar_t/12750.cc: Ditto.
* include/bits/locale_facets.tcc
(time_get::_M_extract_via_format): Tweak to absolutely avoid
dereferencing end iterators.
* include/bits/locale_facets.h (__verify_grouping):
Const-ify second parameter.
* include/bits/locale_facets.tcc (__verify_grouping): Ditto.
* src/locale-inst.cc (__verify_grouping): Ditto.
2003-10-27 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc (num_get::_M_extract_float):
Various things: 1- Avoid absolutely end iterator dereferences;
2- Improve performance-wise the code skipping leading zeros;
3- Fix two bugs wrt early bail out in case of parsing errors
(see testcases); 4- General clean up.
(num_get::_M_extract_int): Likewise, except 3-. Additionally,
use __builtin_expect to favor base 10 inputs.
* testsuite/22_locale/num_get/get/char/7.cc: New.
* testsuite/22_locale/num_get/get/wchar_t/7.cc: Ditto.
2003-10-26 Paolo Carlini <pcarlini@suse.de> 2003-10-26 Paolo Carlini <pcarlini@suse.de>
* testsuite/22_locale/money_put/put/char/1.cc: Clean up. * testsuite/22_locale/money_put/put/char/1.cc: Clean up.

View File

@ -125,7 +125,7 @@ namespace std
template<typename _CharT> template<typename _CharT>
bool bool
__verify_grouping(const basic_string<_CharT>& __grouping, __verify_grouping(const basic_string<_CharT>& __grouping,
basic_string<_CharT>& __grouping_tmp); const basic_string<_CharT>& __grouping_tmp);
// Used by both numeric and monetary facets. // Used by both numeric and monetary facets.
// Inserts "group separator" characters into an array of characters. // Inserts "group separator" characters into an array of characters.

View File

@ -144,51 +144,50 @@ namespace std
const _CharT* __lit = __lc->_M_atoms_in; const _CharT* __lit = __lc->_M_atoms_in;
// First check for sign. // First check for sign.
int __pos = 0; if (__beg != __end)
char_type __c = *__beg;
const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
if ((__plus || __traits_type::eq(__c, __lit[_S_iminus]))
&& __beg != __end)
{ {
__xtrc += __plus ? _S_atoms_in[_S_iplus] : _S_atoms_in[_S_iminus]; const char_type __c = *__beg;
++__pos; const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
__c = *(++__beg); if (__plus || __traits_type::eq(__c, __lit[_S_iminus]))
{
__xtrc += __plus ? _S_atoms_in[_S_iplus]
: _S_atoms_in[_S_iminus];
++__beg;
}
} }
// Next, strip leading zeros. // Next, look for a zero...
bool __found_zero = false; bool __found_mantissa = false;
while (__traits_type::eq(__c, __lit[_S_izero]) && __beg != __end) if (__beg != __end && __traits_type::eq(*__beg, __lit[_S_izero]))
{
__c = *(++__beg);
__found_zero = true;
}
if (__found_zero)
{ {
__xtrc += _S_atoms_in[_S_izero]; __xtrc += _S_atoms_in[_S_izero];
++__pos; __found_mantissa = true;
++__beg;
// ... and skip the additional ones.
for (; __beg != __end
&& __traits_type::eq(*__beg, __lit[_S_izero]); ++__beg);
} }
// Only need acceptable digits for floating point numbers. // Only need acceptable digits for floating point numbers.
bool __found_dec = false; bool __found_dec = false;
bool __found_sci = false; bool __found_sci = false;
string __found_grouping; string __found_grouping;
const size_t __len = _S_iE - _S_izero + 1;
int __sep_pos = 0; int __sep_pos = 0;
bool __e; bool __e;
while (__beg != __end) while (__beg != __end)
{ {
// Only look in digits. // Only look in digits.
const char_type __c = *__beg;
const char_type* __p = __traits_type::find(__lit + _S_izero, 10, const char_type* __p = __traits_type::find(__lit + _S_izero, 10,
__c); __c);
// NB: strchr returns true for *__beg == 0x0
// NB: strchr returns true for __c == 0x0
if (__p && !__traits_type::eq(__c, char_type())) if (__p && !__traits_type::eq(__c, char_type()))
{ {
// Try first for acceptable digit; record it if found. // Try first for acceptable digit; record it if found.
++__pos;
__xtrc += _S_atoms_in[__p - __lit]; __xtrc += _S_atoms_in[__p - __lit];
__found_mantissa = true;
++__sep_pos; ++__sep_pos;
__c = *(++__beg); ++__beg;
} }
else if (__traits_type::eq(__c, __lc->_M_thousands_sep) else if (__traits_type::eq(__c, __lc->_M_thousands_sep)
&& __lc->_M_use_grouping && !__found_dec) && __lc->_M_use_grouping && !__found_dec)
@ -199,7 +198,7 @@ namespace std
{ {
__found_grouping += static_cast<char>(__sep_pos); __found_grouping += static_cast<char>(__sep_pos);
__sep_pos = 0; __sep_pos = 0;
__c = *(++__beg); ++__beg;
} }
else else
{ {
@ -215,28 +214,28 @@ namespace std
// must be adjusted only if __dec comes after some __sep. // must be adjusted only if __dec comes after some __sep.
if (__found_grouping.size()) if (__found_grouping.size())
__found_grouping += static_cast<char>(__sep_pos); __found_grouping += static_cast<char>(__sep_pos);
++__pos;
__xtrc += '.'; __xtrc += '.';
__c = *(++__beg);
__found_dec = true; __found_dec = true;
++__beg;
} }
else if ((__e = __traits_type::eq(__c, __lit[_S_ie]) else if ((__e = __traits_type::eq(__c, __lit[_S_ie])
|| __traits_type::eq(__c, __lit[_S_iE])) || __traits_type::eq(__c, __lit[_S_iE]))
&& !__found_sci && __pos) && __found_mantissa && !__found_sci)
{ {
// Scientific notation. // Scientific notation.
++__pos;
__xtrc += __e ? _S_atoms_in[_S_ie] : _S_atoms_in[_S_iE]; __xtrc += __e ? _S_atoms_in[_S_ie] : _S_atoms_in[_S_iE];
__c = *(++__beg); ++__beg;
// Remove optional plus or minus sign, if they exist. // Remove optional plus or minus sign, if they exist.
const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]); if (__beg != __end)
if (__plus || __traits_type::eq(__c, __lit[_S_iminus]))
{ {
++__pos; const bool __plus = __traits_type::eq(*__beg, __lit[_S_iplus]);
__xtrc += __plus ? _S_atoms_in[_S_iplus] if (__plus || __traits_type::eq(*__beg, __lit[_S_iminus]))
: _S_atoms_in[_S_iminus]; {
__c = *(++__beg); __xtrc += __plus ? _S_atoms_in[_S_iplus]
: _S_atoms_in[_S_iminus];
++__beg;
}
} }
__found_sci = true; __found_sci = true;
} }
@ -288,55 +287,62 @@ namespace std
__base = 10; __base = 10;
// First check for sign. // First check for sign.
char_type __c = *__beg; if (__beg != __end)
const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
if ((__plus || __traits_type::eq(__c, __lit[_S_iminus]))
&& __beg != __end)
{ {
__xtrc += __plus ? _S_atoms_in[_S_iplus] : _S_atoms_in[_S_iminus]; const char_type __c = *__beg;
__c = *(++__beg); const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
if (__plus || __traits_type::eq(__c, __lit[_S_iminus]))
{
__xtrc += __plus ? _S_atoms_in[_S_iplus]
: _S_atoms_in[_S_iminus];
++__beg;
}
} }
// Next, strip leading zeros and check required digits for base formats. // Next, look for leading zeros and check required digits for base formats.
if (__base == 10) if (__builtin_expect(__base == 10, true))
{ {
bool __found_zero = false; // Look for a zero...
while (__traits_type::eq(__c, __lit[_S_izero]) && __beg != __end) if (__beg != __end && __traits_type::eq(*__beg, __lit[_S_izero]))
{
__c = *(++__beg);
__found_zero = true;
}
if (__found_zero)
{ {
__xtrc += _S_atoms_in[_S_izero]; __xtrc += _S_atoms_in[_S_izero];
if (__basefield == 0) ++__beg;
{ // ... and skip the additional ones.
const bool __x = __traits_type::eq(__c, __lit[_S_ix]); for (; __beg != __end
if ((__x || __traits_type::eq(__c, __lit[_S_iX])) && __traits_type::eq(*__beg, __lit[_S_izero]); ++__beg);
&& __beg != __end)
// Check required digits.
if (__beg != __end && __basefield == 0)
{
const bool __x = __traits_type::eq(*__beg, __lit[_S_ix]);
if (__x || __traits_type::eq(*__beg, __lit[_S_iX]))
{ {
__xtrc += __x ? _S_atoms_in[_S_ix] : _S_atoms_in[_S_iX]; __xtrc += __x ? _S_atoms_in[_S_ix]
__c = *(++__beg); : _S_atoms_in[_S_iX];
__base = 16; __base = 16;
++__beg;
} }
else else
__base = 8; __base = 8;
} }
} }
} }
else if (__base == 16) else if (__base == 16)
{ {
if (__traits_type::eq(__c, __lit[_S_izero]) && __beg != __end) if (__beg != __end && __traits_type::eq(*__beg, __lit[_S_izero]))
{ {
__xtrc += _S_atoms_in[_S_izero]; __xtrc += _S_atoms_in[_S_izero];
__c = *(++__beg); ++__beg;
const bool __x = __traits_type::eq(__c, __lit[_S_ix]); if (__beg != __end)
if ((__x || __traits_type::eq(__c, __lit[_S_iX]))
&& __beg != __end)
{ {
__xtrc += __x ? _S_atoms_in[_S_ix] : _S_atoms_in[_S_iX]; const bool __x = __traits_type::eq(*__beg, __lit[_S_ix]);
__c = *(++__beg); if (__x || __traits_type::eq(*__beg, __lit[_S_iX]))
{
__xtrc += __x ? _S_atoms_in[_S_ix]
: _S_atoms_in[_S_iX];
++__beg;
}
} }
} }
} }
@ -347,22 +353,21 @@ namespace std
// Extract. // Extract.
string __found_grouping; string __found_grouping;
const char_type __sep = __lc->_M_thousands_sep;
int __sep_pos = 0; int __sep_pos = 0;
while (__beg != __end) for (; __beg != __end; ++__beg)
{ {
const char_type* __p = __traits_type::find(__lit + _S_izero, const char_type __c = *__beg;
__len, __c); const char_type* __p = __traits_type::find(__lit + _S_izero,
__len, __c);
// NB: strchr returns true for __c == 0x0 // NB: strchr returns true for __c == 0x0
if (__p && !__traits_type::eq(__c, char_type())) if (__p && !__traits_type::eq(__c, char_type()))
{ {
// Try first for acceptable digit; record it if found. // Try first for acceptable digit; record it if found.
__xtrc += _S_atoms_in[__p - __lit]; __xtrc += _S_atoms_in[__p - __lit];
++__sep_pos; ++__sep_pos;
__c = *(++__beg);
} }
else if (__traits_type::eq(__c, __sep) && __lc->_M_use_grouping) else if (__traits_type::eq(__c, __lc->_M_thousands_sep)
&& __lc->_M_use_grouping)
{ {
// NB: Thousands separator at the beginning of a string // NB: Thousands separator at the beginning of a string
// is a no-no, as is two consecutive thousands separators. // is a no-no, as is two consecutive thousands separators.
@ -370,7 +375,6 @@ namespace std
{ {
__found_grouping += static_cast<char>(__sep_pos); __found_grouping += static_cast<char>(__sep_pos);
__sep_pos = 0; __sep_pos = 0;
__c = *(++__beg);
} }
else else
{ {
@ -1609,6 +1613,18 @@ namespace std
_M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
__ctype, __err); __ctype, __err);
break; break;
case 'e':
// Day [1, 31], with single digits preceded by
// space. [tm_mday]
if (__ctype.is(ctype_base::space, *__beg))
_M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, 1,
__ctype, __err);
else if (*__beg != __ctype.widen('0'))
_M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, 2,
__ctype, __err);
else
__err |= ios_base::failbit;
break;
case 'D': case 'D':
// Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
__cs = "%m/%d/%y"; __cs = "%m/%d/%y";
@ -1660,7 +1676,7 @@ namespace std
if (__ctype.narrow(*__beg, 0) == '\t') if (__ctype.narrow(*__beg, 0) == '\t')
++__beg; ++__beg;
else else
__err |= ios_base::failbit; __err |= ios_base::failbit;
break; break;
case 'T': case 'T':
// Equivalent to (%H:%M:%S). // Equivalent to (%H:%M:%S).
@ -1707,10 +1723,9 @@ namespace std
14, __err); 14, __err);
// GMT requires special effort. // GMT requires special effort.
char_type __c = *__beg; if (__beg != __end && !__err && __tmp == 0
if (!__err && __tmp == 0 && (*__beg == __ctype.widen('-')
&& (__c == __ctype.widen('-') || *__beg == __ctype.widen('+')))
|| __c == __ctype.widen('+')))
{ {
_M_extract_num(__beg, __end, __tmp, 0, 23, 2, _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
__ctype, __err); __ctype, __err);
@ -2245,7 +2260,7 @@ namespace std
template<typename _CharT> template<typename _CharT>
bool bool
__verify_grouping(const basic_string<_CharT>& __grouping, __verify_grouping(const basic_string<_CharT>& __grouping,
basic_string<_CharT>& __grouping_tmp) const basic_string<_CharT>& __grouping_tmp)
{ {
size_t __i = 0; size_t __i = 0;
size_t __j = 0; size_t __j = 0;

View File

@ -233,7 +233,8 @@ namespace std
template template
bool bool
__verify_grouping<C>(const basic_string<C>&, basic_string<C>&); __verify_grouping<C>(const basic_string<C>&,
const basic_string<C>&);
template class __pad<C, char_traits<C> >; template class __pad<C, char_traits<C> >;

View File

@ -0,0 +1,58 @@
// 2003-10-25 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2003 Free Software Foundation
//
// 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 2, 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.1.1 num_get members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
void test01()
{
using namespace std;
typedef istreambuf_iterator<char> iterator_type;
bool test __attribute__((unused)) = true;
// cache the num_get facet
istringstream iss;
const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
ios_base::iostate err = ios_base::goodbit;
iterator_type end;
double d;
iss.str("+e3");
end = ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( err == ios_base::failbit );
VERIFY( *end == 'e' );
iss.str(".e+1");
iss.clear();
err = ios_base::goodbit;
end = ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( err == ios_base::failbit );
VERIFY( *end == 'e' );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,58 @@
// 2003-10-25 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2003 Free Software Foundation
//
// 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 2, 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.1.1 num_get members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
void test01()
{
using namespace std;
typedef istreambuf_iterator<wchar_t> iterator_type;
bool test __attribute__((unused)) = true;
// cache the num_get facet
wistringstream iss;
const num_get<wchar_t>& ng = use_facet<num_get<wchar_t> >(iss.getloc());
ios_base::iostate err = ios_base::goodbit;
iterator_type end;
double d;
iss.str(L"+e3");
end = ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( err == ios_base::failbit );
VERIFY( *end == L'e' );
iss.str(L".e+1");
iss.clear();
err = ios_base::goodbit;
end = ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( err == ios_base::failbit );
VERIFY( *end == L'e' );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,79 @@
// 2003-10-27 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2003 Free Software Foundation
//
// 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 2, 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.5.1.1 time_get members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
// libstdc++/12750
void test01()
{
using namespace std;
typedef istreambuf_iterator<char> iterator_type;
bool test __attribute__((unused)) = true;
// basic construction
locale loc_is = __gnu_test::try_named_locale("is_IS");
// create an ostream-derived object, cache the time_get facet
iterator_type end;
istringstream iss;
const time_get<char>& tim_get = use_facet<time_get<char> >(iss.getloc());
const ios_base::iostate good = ios_base::goodbit;
ios_base::iostate errorstate = good;
// create "C" time objects
const tm time_bday01 = { 0, 0, 12, 2, 9, 103, 4, 274, -1 };
const tm time_bday02 = { 0, 0, 12, 26, 9, 103, 0, 298, -1 };
// inspection of named locales, is_IS
iss.imbue(loc_is);
iss.str("Fim 2.Okt 2003");
iterator_type is_it01(iss);
tm time01;
errorstate = good;
tim_get.get_date(is_it01, end, iss, errorstate, &time01);
VERIFY( time01.tm_mon == time_bday01.tm_mon );
VERIFY( time01.tm_mday == time_bday01.tm_mday );
VERIFY( time01.tm_year == time_bday01.tm_year );
VERIFY( errorstate == ios_base::eofbit );
iss.str("Sun 26.Okt 2003");
iterator_type is_it02(iss);
tm time02;
errorstate = good;
tim_get.get_date(is_it02, end, iss, errorstate, &time02);
VERIFY( time02.tm_mon == time_bday02.tm_mon );
VERIFY( time02.tm_mday == time_bday02.tm_mday );
VERIFY( time02.tm_year == time_bday02.tm_year );
VERIFY( errorstate == ios_base::eofbit );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,79 @@
// 2003-10-27 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2003 Free Software Foundation
//
// 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 2, 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.5.1.1 time_get members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
// libstdc++/12750
void test01()
{
using namespace std;
typedef istreambuf_iterator<wchar_t> iterator_type;
bool test __attribute__((unused)) = true;
// basic construction
locale loc_is = __gnu_test::try_named_locale("is_IS");
// create an ostream-derived object, cache the time_get facet
iterator_type end;
wistringstream iss;
const time_get<wchar_t>& tim_get = use_facet<time_get<wchar_t> >(iss.getloc());
const ios_base::iostate good = ios_base::goodbit;
ios_base::iostate errorstate = good;
// create "C" time objects
const tm time_bday01 = { 0, 0, 12, 2, 9, 103, 4, 274, -1 };
const tm time_bday02 = { 0, 0, 12, 26, 9, 103, 0, 298, -1 };
// inspection of named locales, is_IS
iss.imbue(loc_is);
iss.str(L"Fim 2.Okt 2003");
iterator_type is_it01(iss);
tm time01;
errorstate = good;
tim_get.get_date(is_it01, end, iss, errorstate, &time01);
VERIFY( time01.tm_mon == time_bday01.tm_mon );
VERIFY( time01.tm_mday == time_bday01.tm_mday );
VERIFY( time01.tm_year == time_bday01.tm_year );
VERIFY( errorstate == ios_base::eofbit );
iss.str(L"Sun 26.Okt 2003");
iterator_type is_it02(iss);
tm time02;
errorstate = good;
tim_get.get_date(is_it02, end, iss, errorstate, &time02);
VERIFY( time02.tm_mon == time_bday02.tm_mon );
VERIFY( time02.tm_mday == time_bday02.tm_mday );
VERIFY( time02.tm_year == time_bday02.tm_year );
VERIFY( errorstate == ios_base::eofbit );
}
int main()
{
test01();
return 0;
}