On 15/04/14 23:19 +0200, RĂ¼diger Sonderfeld wrote:
+ TESTHEAD("check broken format"); + iss.str("2014-04-14 01:09:35"); + format = "%"; + ret = tget.get(istreambuf_iterator<char>(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err == ios_base::failbit); + + TESTHEAD("check single format letter version"); + iss.str("2020"); + ret = tget.get(istreambuf_iterator<char>(iss), end, iss, err, &time, 'Y'); + VERIFY(err == ios_base::goodbit); + VERIFY(time.tm_year == 120); + VERIFY(ret == end); + + TESTHEAD("check skipping of space"); + iss.str("2010 07 01"); + format = "%Y %m %d"; + ret = tget.get(istreambuf_iterator<char>(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err == ios_base::goodbit); + VERIFY(time.tm_year == 110); + VERIFY(time.tm_mon == 7);
This fails because tm_mon is zero-indexed, so the result is 6
+ VERIFY(time.tm_mday == 1); + VERIFY(ret == end); + + TESTHEAD("check mismatch"); + iss.str("year: 1970"); + format = "jahr: 1970"; + ret = tget.get(istreambuf_iterator<char>(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err == ios_base::failbit); + VERIFY(ret == istreambuf_iterator<char>(iss)); + + TESTHEAD("check case insensitive match"); + iss.str("yEaR: 1980"); + format = "YeAR: 1980"; + ret = tget.get(istreambuf_iterator<char>(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err == ios_base::goodbit); + VERIFY(ret == end); + VERIFY(time.tm_year == 80);
This test can never pass because the format has 1980 instead of %Y Apparently the tests in this patch have never been run :-( I think I've fixed them now though, and am committing the attached patch to trunk.
commit 6ffbe32df8431a97d219941579b09ba238816aef Author: Jonathan Wakely <jwak...@redhat.com> Date: Fri Dec 19 00:02:02 2014 +0000 2014-12-22 R??diger Sonderfeld <ruedi...@c-plusplus.de> Jonathan Wakely <jwak...@redhat.com> PR libstdc++/60396 * config/abi/pre/gnu.ver: Add new exports. * include/bits/locale_facets_nonio.h (time_get::get): New overloads. (time_get::do_get): New virtual function. * include/bits/locale_facets_nonio.tcc (time_get::get): Define. (time_get::do_get): Define. * src/c++11/string-inst.cc (time_get::get, time_get::do_get): Add C++11-only instantiations. * testsuite/22_locale/time_get/get/char/1.cc: New. * testsuite/22_locale/time_get/get/char/2.cc: New. * testsuite/22_locale/time_get/get/wchar_t/1.cc: New. * testsuite/22_locale/time_get/get/wchar_t/2.cc: New. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 8ba8ed4..6602532 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -1748,6 +1748,10 @@ GLIBCXX_3.4.21 { _ZNKSt3tr14hashINSt7__cxx1112basic_string*; + # std::time_get::get + _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPK[cw]SC_; + _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc; + } GLIBCXX_3.4.20; diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h b/libstdc++-v3/include/bits/locale_facets_nonio.h index 9c629e2..a9feaec 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.h +++ b/libstdc++-v3/include/bits/locale_facets_nonio.h @@ -537,6 +537,54 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ios_base::iostate& __err, tm* __tm) const { return this->do_get_year(__beg, __end, __io, __err, __tm); } +#if __cplusplus >= 201103L + /** + * @brief Parse input string according to format. + * + * This function calls time_get::do_get with the provided + * parameters. @see do_get() and get(). + * + * @param __s Start of string to parse. + * @param __end End of string to parse. + * @param __io Source of the locale. + * @param __err Error flags to set. + * @param __tm Pointer to struct tm to fill in. + * @param __format Format specifier. + * @param __modifier Format modifier. + * @return Iterator to first char not parsed. + */ + inline + iter_type get(iter_type __s, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, char __format, + char __modifier = 0) const + { + return this->do_get(__s, __end, __io, __err, __tm, __format, + __modifier); + } + + /** + * @brief Parse input string according to format. + * + * This function parses the input string according to a + * provided format string. It does the inverse of + * time_put::put. The format string follows the format + * specified for strftime(3)/strptime(3). The actual parsing + * is done by time_get::do_get. + * + * @param __s Start of string to parse. + * @param __end End of string to parse. + * @param __io Source of the locale. + * @param __err Error flags to set. + * @param __tm Pointer to struct tm to fill in. + * @param __fmt Start of the format string. + * @param __fmtend End of the format string. + * @return Iterator to first char not parsed. + */ + iter_type get(iter_type __s, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, const char_type* __fmt, + const char_type* __fmtend) const; +#endif // __cplusplus >= 201103L + protected: /// Destructor. virtual @@ -650,6 +698,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 do_get_year(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const; +#if __cplusplus >= 201103L + /** + * @brief Parse input string according to format. + * + * This function parses the string according to the provided + * format and optional modifier. This function is a hook for + * derived classes to change the value returned. @see get() + * for more details. + * + * @param __s Start of string to parse. + * @param __end End of string to parse. + * @param __io Source of the locale. + * @param __err Error flags to set. + * @param __tm Pointer to struct tm to fill in. + * @param __format Format specifier. + * @param __modifier Format modifier. + * @return Iterator to first char not parsed. + */ +#if _GLIBCXX_USE_CXX11_ABI + virtual +#endif + iter_type + do_get(iter_type __s, iter_type __end, ios_base& __f, + ios_base::iostate& __err, tm* __tm, + char __format, char __modifier) const; +#endif // __cplusplus >= 201103L + // Extract numeric component of length __len. iter_type _M_extract_num(iter_type __beg, iter_type __end, int& __member, diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc index 200168d..b0f89ae 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc +++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc @@ -1141,6 +1141,113 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 return __beg; } +#if __cplusplus >= 201103L + template<typename _CharT, typename _InIter> + inline + _InIter + time_get<_CharT, _InIter>:: + get(iter_type __s, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, const char_type* __fmt, + const char_type* __fmtend) const + { + const locale& __loc = __io._M_getloc(); + ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); + __err = ios_base::goodbit; + while (__fmt != __fmtend && + __err == ios_base::goodbit) + { + if (__s == __end) + { + __err = ios_base::eofbit | ios_base::failbit; + break; + } + else if (__ctype.narrow(*__fmt, 0) == '%') + { + char __format; + char __mod = 0; + if (++__fmt == __fmtend) + { + __err = ios_base::failbit; + break; + } + const char __c = __ctype.narrow(*__fmt, 0); + if (__c != 'E' && __c != 'O') + __format = __c; + else if (++__fmt != __fmtend) + { + __mod = __c; + __format = __ctype.narrow(*__fmt, 0); + } + else + { + __err = ios_base::failbit; + break; + } + __s = this->do_get(__s, __end, __io, __err, __tm, __format, + __mod); + ++__fmt; + } + else if (__ctype.is(ctype_base::space, *__fmt)) + { + ++__fmt; + while (__fmt != __fmtend && + __ctype.is(ctype_base::space, *__fmt)) + ++__fmt; + + while (__s != __end && + __ctype.is(ctype_base::space, *__s)) + ++__s; + } + // TODO real case-insensitive comparison + else if (__ctype.tolower(*__s) == __ctype.tolower(*__fmt) || + __ctype.toupper(*__s) == __ctype.toupper(*__fmt)) + { + ++__s; + ++__fmt; + } + else + { + __err = ios_base::failbit; + break; + } + } + return __s; + } + + template<typename _CharT, typename _InIter> + inline + _InIter + time_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + char __format, char __mod) const + { + const locale& __loc = __io._M_getloc(); + ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); + __err = ios_base::goodbit; + + char_type __fmt[4]; + __fmt[0] = __ctype.widen('%'); + if (!__mod) + { + __fmt[1] = __format; + __fmt[2] = char_type(); + } + else + { + __fmt[1] = __mod; + __fmt[2] = __format; + __fmt[3] = char_type(); + } + + __beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __fmt); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + +#endif // __cplusplus >= 201103L + template<typename _CharT, typename _OutIter> _OutIter time_put<_CharT, _OutIter>:: diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc index a892d5d..a25ce20 100644 --- a/libstdc++-v3/src/c++11/string-inst.cc +++ b/libstdc++-v3/src/c++11/string-inst.cc @@ -113,3 +113,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION } // namespace + +// TODO does not belong here! +#include <locale> +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + template istreambuf_iterator<C> time_get<C, istreambuf_iterator<C> >::get(iter_type, iter_type, ios_base&, ios_base::iostate&, tm*, char, char) const; + template istreambuf_iterator<C> time_get<C, istreambuf_iterator<C> >::do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, tm*, char, char) const; + template istreambuf_iterator<C> time_get<C, istreambuf_iterator<C> >::get(iter_type, iter_type, ios_base&, ios_base::iostate&, tm*, const char_type*, const char_type*) const; +_GLIBCXX_END_NAMESPACE_CXX11 +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/char/1.cc b/libstdc++-v3/testsuite/22_locale/time_get/get/char/1.cc new file mode 100644 index 0000000..19ca7ac --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/time_get/get/char/1.cc @@ -0,0 +1,132 @@ +// { dg-options " -std=gnu++11 " } + +// 2014-04-14 R??diger Sonderfeld <ruedi...@c-plusplus.de> + +// Copyright (C) 2014 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/>. + +// 22.4.5.1.1 (C++11) time_get members [locale.time.get.members] + +#include <locale> +#include <sstream> +#include <iterator> +#include <testsuite_hooks.h> + +#ifndef _GLIBCXX_ASSERT +# include <iostream> +# define PRINT(x) cout << #x << ": " << x << endl +# define TESTHEAD(x) cout << x << endl +#else +# define PRINT(x) do {} while(false) +# define TESTHEAD(x) do {} while(false) +#endif + +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + 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; + + // check regular operations with format string + TESTHEAD("regular operations"); + iss.str("d 2014-04-14 01:09:35"); + string format = "d %Y-%m-%d %H:%M:%S"; + auto ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + PRINT(err); + VERIFY(err == ios_base::eofbit); + VERIFY(ret == end); + PRINT(time.tm_year); + VERIFY(time.tm_year == 114); + PRINT(time.tm_mon); + VERIFY(time.tm_mon == 3); + PRINT(time.tm_mday); + VERIFY(time.tm_mday == 14); + PRINT(time.tm_hour); + VERIFY(time.tm_hour == 1); + PRINT(time.tm_min); + VERIFY(time.tm_min == 9); + PRINT(time.tm_sec); + VERIFY(time.tm_sec == 35); + + TESTHEAD("check eof"); + iss.str("2020 "); + format = "%Y"; + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err != ios_base::eofbit); + VERIFY(time.tm_year == 120); + VERIFY(ret != end); + + TESTHEAD("check broken format"); + iss.str("2014-04-14 01:09:35"); + format = "%"; + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err == ios_base::failbit); + + TESTHEAD("check single format letter version"); + iss.str("2020"); + ret = tget.get(iter(iss), end, iss, err, &time, 'Y'); + VERIFY(err == ios_base::eofbit); + VERIFY(time.tm_year == 120); + VERIFY(ret == end); + + TESTHEAD("check skipping of space"); + iss.str("2010 07 01"); + format = "%Y %m %d"; + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err == ios_base::eofbit); + VERIFY(time.tm_year == 110); + VERIFY(time.tm_mon == 6); + VERIFY(time.tm_mday == 1); + VERIFY(ret == end); + + TESTHEAD("check mismatch"); + iss.str("year: 1970"); + format = "jahr: %Y"; + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err == ios_base::failbit); + VERIFY(ret == iter(iss)); + + TESTHEAD("check case insensitive match"); + iss.str("yEaR: 1980"); + format = "YeAR: %Y"; + 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_year == 80); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/char/2.cc b/libstdc++-v3/testsuite/22_locale/time_get/get/char/2.cc new file mode 100644 index 0000000..3a04931 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/time_get/get/char/2.cc @@ -0,0 +1,104 @@ +// { dg-require-namedlocale "de_DE.utf8" } +// { dg-options " -std=gnu++11 " } + +// 2014-04-14 R??diger Sonderfeld <ruedi...@c-plusplus.de> + +// Copyright (C) 2014 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/>. + +// 22.4.5.1.1 (C++11) time_get members [locale.time.get.members] + +#include <locale> +#include <sstream> +#include <testsuite_hooks.h> + +#ifndef _GLIBCXX_ASSERT +# include <iostream> +# define PRINT(x) cout << #x << ": " << x << endl +# define TESTHEAD(x) cout << x << endl +#else +# define PRINT(x) do {} while(false) +# define TESTHEAD(x) do {} while(false) +#endif + +void test02() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + locale loc_c = locale::classic(); + locale loc_de = locale("de_DE.utf8"); + VERIFY( loc_de != loc_c ); + + istringstream iss; + iss.imbue(loc_de); + const time_get<char>& tget = use_facet<time_get<char>>(iss.getloc()); + typedef istreambuf_iterator<char> iter; + const iter end; + + ios_base::iostate err; + tm time; + + TESTHEAD("German locale test"); + iss.str("Montag, den 14. April 2014"); + string format = "%A, den %d. %B %Y"; + auto ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + PRINT(err); + VERIFY(err == ios_base::eofbit); + PRINT(time.tm_year); + VERIFY(time.tm_year == 114); + PRINT(time.tm_mon); + VERIFY(time.tm_mon == 3); + PRINT(time.tm_wday); + VERIFY(time.tm_wday == 1); + PRINT(time.tm_mday); + VERIFY(time.tm_mday == 14); + VERIFY(end == end); + + TESTHEAD("German locale: Check case-insensitivity"); + tm time2; + iss.str("Montag, den 14. April 2014"); + format = "%A, DEN %d. %B %Y"; // check case-insensitivity + ret = tget.get(iter(iss), end, iss, err, &time2, + format.data(), format.data()+format.size()); + PRINT(err); + VERIFY(err == ios_base::eofbit); + PRINT(time2.tm_year); + VERIFY(time2.tm_year == 114); + PRINT(time2.tm_mon); + VERIFY(time2.tm_mon == 3); + PRINT(time2.tm_wday); + VERIFY(time2.tm_wday == 1); + PRINT(time2.tm_mday); + VERIFY(time2.tm_mday == 14); + VERIFY(end == end); + + TESTHEAD("German locale: Check single"); + iss.str("Mittwoch"); + ret = tget.get(iter(iss), end, iss, err, &time, 'A'); + PRINT(err); + VERIFY(err == ios_base::eofbit); + PRINT(time.tm_wday); + VERIFY(time.tm_wday == 3); + VERIFY(end == end); +} + +int main() +{ + test02(); +} diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/1.cc b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/1.cc new file mode 100644 index 0000000..5668871 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/1.cc @@ -0,0 +1,132 @@ +// { dg-options " -std=gnu++11 " } + +// 2014-04-14 R??diger Sonderfeld <ruedi...@c-plusplus.de> + +// Copyright (C) 2014 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/>. + +// 22.4.5.1.1 (C++11) time_get members [locale.time.get.members] + +#include <locale> +#include <sstream> +#include <iterator> +#include <testsuite_hooks.h> + +#ifndef _GLIBCXX_ASSERT +# include <iostream> +# define PRINT(x) cout << #x << ": " << x << endl +# define TESTHEAD(x) cout << x << endl +#else +# define PRINT(x) do {} while(false) +# define TESTHEAD(x) do {} while(false) +#endif + +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + 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; + + // check regular operations with format string + TESTHEAD("regular operations"); + iss.str(L"d 2014-04-14 01:09:35"); + wstring format = L"d %Y-%m-%d %H:%M:%S"; + auto ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + PRINT(err); + VERIFY(err == ios_base::eofbit); + VERIFY(ret == end); + PRINT(time.tm_year); + VERIFY(time.tm_year == 114); + PRINT(time.tm_mon); + VERIFY(time.tm_mon == 3); + PRINT(time.tm_mday); + VERIFY(time.tm_mday == 14); + PRINT(time.tm_hour); + VERIFY(time.tm_hour == 1); + PRINT(time.tm_min); + VERIFY(time.tm_min == 9); + PRINT(time.tm_sec); + VERIFY(time.tm_sec == 35); + + TESTHEAD("check eof"); + iss.str(L"2020 "); + format = L"%Y"; + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err != ios_base::eofbit); + VERIFY(time.tm_year == 120); + VERIFY(ret != end); + + TESTHEAD("check broken format"); + iss.str(L"2014-04-14 01:09:35"); + format = L"%"; + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err == ios_base::failbit); + + TESTHEAD("check single format letter version"); + iss.str(L"2020"); + ret = tget.get(iter(iss), end, iss, err, &time, L'Y'); + VERIFY(err == ios_base::eofbit); + VERIFY(time.tm_year == 120); + VERIFY(ret == end); + + TESTHEAD(L"check skipping of space"); + iss.str(L"2010 07 01"); + format = L"%Y %m %d"; + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err == ios_base::eofbit); + VERIFY(time.tm_year == 110); + VERIFY(time.tm_mon == 6); + VERIFY(time.tm_mday == 1); + VERIFY(ret == end); + + TESTHEAD("check mismatch"); + iss.str(L"year: 1970"); + format = L"jahr: %Y"; + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY(err == ios_base::failbit); + VERIFY(ret == iter(iss)); + + TESTHEAD("check case insensitive match"); + iss.str(L"yEaR: 1980"); + format = L"YeAR: %Y"; + 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_year == 80); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/2.cc b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/2.cc new file mode 100644 index 0000000..9ec51e2 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/2.cc @@ -0,0 +1,104 @@ +// { dg-require-namedlocale "de_DE.utf8" } +// { dg-options " -std=gnu++11 " } + +// 2014-04-14 R??diger Sonderfeld <ruedi...@c-plusplus.de> + +// Copyright (C) 2014 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/>. + +// 22.4.5.1.1 (C++11) time_get members [locale.time.get.members] + +#include <locale> +#include <sstream> +#include <testsuite_hooks.h> + +#ifndef _GLIBCXX_ASSERT +# include <iostream> +# define PRINT(x) cout << #x << ": " << x << endl +# define TESTHEAD(x) cout << x << endl +#else +# define PRINT(x) do {} while(false) +# define TESTHEAD(x) do {} while(false) +#endif + +void test02() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + locale loc_c = locale::classic(); + locale loc_de = locale("de_DE.utf8"); + VERIFY( loc_de != loc_c ); + + wistringstream iss; + iss.imbue(loc_de); + const time_get<wchar_t>& tget = use_facet<time_get<wchar_t>>(iss.getloc()); + typedef istreambuf_iterator<wchar_t> iter; + const iter end; + + ios_base::iostate err; + tm time; + + TESTHEAD("German locale test"); + iss.str(L"Montag, den 14. April 2014"); + wstring format = L"%A, den %d. %B %Y"; + auto ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + PRINT(err); + VERIFY(err == ios_base::eofbit); + PRINT(time.tm_year); + VERIFY(time.tm_year == 114); + PRINT(time.tm_mon); + VERIFY(time.tm_mon == 3); + PRINT(time.tm_wday); + VERIFY(time.tm_wday == 1); + PRINT(time.tm_mday); + VERIFY(time.tm_mday == 14); + VERIFY(end == end); + + TESTHEAD("German locale: Check case-insensitivity"); + tm time2; + iss.str(L"Montag, den 14. April 2014"); + format = L"%A, DEN %d. %B %Y"; // check case-insensitivity + ret = tget.get(iter(iss), end, iss, err, &time2, + format.data(), format.data()+format.size()); + PRINT(err); + VERIFY(err == ios_base::eofbit); + PRINT(time2.tm_year); + VERIFY(time2.tm_year == 114); + PRINT(time2.tm_mon); + VERIFY(time2.tm_mon == 3); + PRINT(time2.tm_wday); + VERIFY(time2.tm_wday == 1); + PRINT(time2.tm_mday); + VERIFY(time2.tm_mday == 14); + VERIFY(end == end); + + TESTHEAD("German locale: Check single"); + iss.str(L"Mittwoch"); + ret = tget.get(iter(iss), end, iss, err, &time, L'A'); + PRINT(err); + VERIFY(err == ios_base::eofbit); + PRINT(time.tm_wday); + VERIFY(time.tm_wday == 3); + VERIFY(end == end); +} + +int main() +{ + test02(); +}