re PR libstdc++/60396 (Missing time_get<>::get() functions)
authorRüdiger Sonderfeld <ruediger@c-plusplus.de>
Mon, 22 Dec 2014 13:45:44 +0000 (13:45 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 22 Dec 2014 13:45:44 +0000 (13:45 +0000)
2014-12-22  Rüdiger Sonderfeld  <ruediger@c-plusplus.de>
    Jonathan Wakely  <jwakely@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.

Co-Authored-By: Jonathan Wakely <jwakely@redhat.com>
From-SVN: r219012

libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/include/bits/locale_facets_nonio.h
libstdc++-v3/include/bits/locale_facets_nonio.tcc
libstdc++-v3/src/c++11/string-inst.cc
libstdc++-v3/testsuite/22_locale/time_get/get/char/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/time_get/get/char/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/2.cc [new file with mode: 0644]

index 54dabac154baa7196a6c051cfc503b5a6c208bbc..41a91c54524f1a4952543b331435c31876860ddd 100644 (file)
@@ -1,3 +1,19 @@
+2014-12-22  Rüdiger Sonderfeld  <ruediger@c-plusplus.de>
+           Jonathan Wakely  <jwakely@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.
+
 2014-12-21  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/64367
index 8ba8ed4dba9fd0ff5c56d5ca4d70b7207c115f60..6602532ef79074872bc7c1332c5f6cee41ce370b 100644 (file)
@@ -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;
 
 
index 9c629e240d737b4859c857877fef6d2408e9da17..a9feaec7dfbf88f0cca8963df2e5341d47e380bd 100644 (file)
@@ -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,
index 200168da2507dfefbe2a7bbeb6daa9675cc25153..b0f89aec7a20f8b1b2db8b22af364451e8113062 100644 (file)
@@ -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>::
index a892d5d52d9d95337a2870417e2b39a424ba3abf..a25ce206e8f3928ebe0ada647baea2f9f4fb0cec 100644 (file)
@@ -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 (file)
index 0000000..19ca7ac
--- /dev/null
@@ -0,0 +1,132 @@
+// { dg-options " -std=gnu++11 " }
+
+// 2014-04-14 Rüdiger Sonderfeld  <ruediger@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 (file)
index 0000000..3a04931
--- /dev/null
@@ -0,0 +1,104 @@
+// { dg-require-namedlocale "de_DE.utf8" }
+// { dg-options " -std=gnu++11 " }
+
+// 2014-04-14 Rüdiger Sonderfeld  <ruediger@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 (file)
index 0000000..5668871
--- /dev/null
@@ -0,0 +1,132 @@
+// { dg-options " -std=gnu++11 " }
+
+// 2014-04-14 Rüdiger Sonderfeld  <ruediger@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 (file)
index 0000000..9ec51e2
--- /dev/null
@@ -0,0 +1,104 @@
+// { dg-require-namedlocale "de_DE.utf8" }
+// { dg-options " -std=gnu++11 " }
+
+// 2014-04-14 Rüdiger Sonderfeld  <ruediger@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();
+}