OSDN Git Service

2010-01-06 Paolo Carlini <paolo.carlini@oracle.com>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Jan 2010 00:22:51 +0000 (00:22 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Jan 2010 00:22:51 +0000 (00:22 +0000)
PR libstdc++/26701
* include/bits/locale_facets_nonio.tcc (time_get<>::_M_extract_num):
Encode short two digits over four parsings to negative numbers.
(time_get<>::_M_extract_via_format): Adjust, accept both two digits
and four digits for both 'y' and 'Y'.
(time_get<>::do_get_year): Call time_get<>::_M_extract_num.
* doc/xml/manual/prerequisites.xml: Add en_GB.
* testsuite/lib/libstdc++.exp: Adjust
* testsuite/22_locale/time_get/get_date/char/26701.cc: New.
* testsuite/22_locale/time_get/get_date/wchar_t/26701.cc: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@155685 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/doc/xml/manual/prerequisites.xml
libstdc++-v3/include/bits/locale_facets_nonio.tcc
libstdc++-v3/testsuite/22_locale/time_get/get_date/char/26701.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/time_get/get_date/wchar_t/26701.cc [new file with mode: 0644]
libstdc++-v3/testsuite/lib/libstdc++.exp

index 02c19c1..cb10263 100644 (file)
@@ -1,3 +1,16 @@
+2010-01-06  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR libstdc++/26701
+       * include/bits/locale_facets_nonio.tcc (time_get<>::_M_extract_num):
+       Encode short two digits over four parsings to negative numbers.
+       (time_get<>::_M_extract_via_format): Adjust, accept both two digits
+       and four digits for both 'y' and 'Y'.
+       (time_get<>::do_get_year): Call time_get<>::_M_extract_num.
+       * doc/xml/manual/prerequisites.xml: Add en_GB.
+       * testsuite/lib/libstdc++.exp: Adjust
+       * testsuite/22_locale/time_get/get_date/char/26701.cc: New.
+       * testsuite/22_locale/time_get/get_date/wchar_t/26701.cc: Likewise.
+
 2010-01-06  Benjamin Kosnik  <bkoz@redhat.com>
 
        PR libstdc++/42491
index 6a55e0c..8391fe4 100644 (file)
@@ -73,6 +73,7 @@
 <programlisting>
 de_DE               ISO-8859-1
 de_DE@euro          ISO-8859-15
+en_GB               ISO-8859-1
 en_HK               ISO-8859-1
 en_PH               ISO-8859-1
 en_US               ISO-8859-1
index 73cd747..e788457 100644 (file)
@@ -778,16 +778,16 @@ _GLIBCXX_END_LDBL_NAMESPACE
                  break;
                case 'y':
                case 'C': // C99
-                 // Two digit year. [tm_year]
-                 __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
-                                        __io, __tmperr);
-                 break;
+                 // Two digit year.
                case 'Y':
-                 // Year [1900). [tm_year]
+                 // Year [1900).
+                 // NB: We parse either two digits, implicitly years since
+                 // 1900, or 4 digits, full year.  In both cases we can 
+                 // reconstruct [tm_year].  See also libstdc++/26701.
                  __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4,
                                         __io, __tmperr);
                  if (!__tmperr)
-                   __tm->tm_year = __mem - 1900;
+                   __tm->tm_year = __mem < 0 ? __mem + 100 : __mem - 1900;
                  break;
                case 'Z':
                  // Timezone info.
@@ -865,6 +865,9 @@ _GLIBCXX_END_LDBL_NAMESPACE
        }
       if (__i == __len)
        __member = __value;
+      // Special encoding for do_get_year, 'y', and 'Y' above.
+      else if (__len == 4 && __i == 2)
+       __member = __value - 100;
       else
        __err |= ios_base::failbit;
 
@@ -1116,19 +1119,13 @@ _GLIBCXX_END_LDBL_NAMESPACE
     {
       const locale& __loc = __io._M_getloc();
       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+      int __tmpyear;
+      ios_base::iostate __tmperr = ios_base::goodbit;
 
-      size_t __i = 0;
-      int __value = 0;
-      for (; __beg != __end && __i < 4; ++__beg, ++__i)
-       {
-         const char __c = __ctype.narrow(*__beg, '*');
-         if (__c >= '0' && __c <= '9')
-           __value = __value * 10 + (__c - '0');
-         else
-           break;
-       }
-      if (__i == 2 || __i == 4)
-       __tm->tm_year = __i == 2 ? __value : __value - 1900;
+      __beg = _M_extract_num(__beg, __end, __tmpyear, 0, 9999, 4,
+                            __io, __tmperr);
+      if (!__tmperr)
+       __tm->tm_year = __tmpyear < 0 ? __tmpyear + 100 : __tmpyear - 1900;
       else
        __err |= ios_base::failbit;
 
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_date/char/26701.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_date/char/26701.cc
new file mode 100644 (file)
index 0000000..b02fefe
--- /dev/null
@@ -0,0 +1,64 @@
+// { dg-require-namedlocale "" }
+
+// 2010-01-06  Paolo Carlini  <paolo.carlini@oracle.com>
+
+// Copyright (C) 2010 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 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.2.5.1.1 time_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/26701
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  typedef istreambuf_iterator<char> iterator_type;
+
+  locale loc_en = locale("en_GB");
+  
+  tm tm0 = __gnu_test::test_tm(0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+  iterator_type end;
+
+  istringstream iss; 
+  iss.imbue(loc_en);
+  const time_get<char>& tg = use_facet<time_get<char> >(iss.getloc());
+
+  const ios_base::iostate good = ios_base::goodbit;
+  ios_base::iostate errorstate = good;
+
+  iss.str("01/02/2003");
+  iterator_type is_it0(iss);
+  
+  errorstate = good;
+  tg.get_date(is_it0, end, iss, errorstate, &tm0);
+  VERIFY( errorstate == ios_base::eofbit );
+  VERIFY( tm0.tm_year + 1900 == 2003 );
+  VERIFY( tm0.tm_mon + 1 == 2 );
+  VERIFY( tm0.tm_mday == 1 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_date/wchar_t/26701.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_date/wchar_t/26701.cc
new file mode 100644 (file)
index 0000000..2f4980a
--- /dev/null
@@ -0,0 +1,64 @@
+// { dg-require-namedlocale "" }
+
+// 2010-01-06  Paolo Carlini  <paolo.carlini@oracle.com>
+
+// Copyright (C) 2010 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 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.2.5.1.1 time_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/26701
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  typedef istreambuf_iterator<wchar_t> iterator_type;
+
+  locale loc_en = locale("en_GB");
+  
+  tm tm0 = __gnu_test::test_tm(0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+  iterator_type end;
+
+  wistringstream iss; 
+  iss.imbue(loc_en);
+  const time_get<wchar_t>& tg = use_facet<time_get<wchar_t> >(iss.getloc());
+
+  const ios_base::iostate good = ios_base::goodbit;
+  ios_base::iostate errorstate = good;
+
+  iss.str(L"01/02/2003");
+  iterator_type is_it0(iss);
+  
+  errorstate = good;
+  tg.get_date(is_it0, end, iss, errorstate, &tm0);
+  VERIFY( errorstate == ios_base::eofbit );
+  VERIFY( tm0.tm_year + 1900 == 2003 );
+  VERIFY( tm0.tm_mon + 1 == 2 );
+  VERIFY( tm0.tm_mday == 1 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
index 09cae6d..45a43de 100644 (file)
@@ -869,6 +869,7 @@ proc check_v3_target_namedlocale { } {
        puts $f "     locale(\"de_DE\");"
        puts $f "     locale(\"de_DE.ISO-8859-15@euro\");"
        puts $f "     locale(\"de_DE@euro\");"
+       puts $f "     locale(\"en_GB\");"
        puts $f "     locale(\"en_HK\");"
        puts $f "     locale(\"en_PH\");"
        puts $f "     locale(\"en_US\");"