OSDN Git Service

2010-01-05 Paolo Carlini <paolo.carlini@oracle.com>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Jan 2010 20:05:20 +0000 (20:05 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Jan 2010 20:05:20 +0000 (20:05 +0000)
PR libstdc++/38081
* include/bits/locale_facets_nonio.h (time_get<>::
_M_extract_wday_or_month): New, declare.
* include/bits/locale_facets_nonio.tcc (time_get<>::
_M_extract_wday_or_month): Define.
(time_get<>::do_get_weekday, time_get<>::do_get_monthname): Use it.
* config/abi/pre/gnu.ver: Export new symbols.
* doc/xml/manual/prerequisites.xml: Add ru_RU.UTF-8 and
ru_RU.ISO-8859-5.
* testsuite/lib/libstdc++.exp: Adjust.
* testsuite/22_locale/time_get/get_weekday/char/38081-1.cc: New.
* testsuite/22_locale/time_get/get_weekday/char/38081-2.cc: Likewise.

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

libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/doc/xml/manual/prerequisites.xml
libstdc++-v3/include/bits/locale_facets_nonio.h
libstdc++-v3/include/bits/locale_facets_nonio.tcc
libstdc++-v3/testsuite/22_locale/time_get/get_weekday/char/38081-1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/time_get/get_weekday/char/38081-2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/lib/libstdc++.exp

index 5b2e5d7..f15f43d 100644 (file)
@@ -1,3 +1,18 @@
+2010-01-05  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR libstdc++/38081
+       * include/bits/locale_facets_nonio.h (time_get<>::
+       _M_extract_wday_or_month): New, declare.
+       * include/bits/locale_facets_nonio.tcc (time_get<>::
+       _M_extract_wday_or_month): Define.
+       (time_get<>::do_get_weekday, time_get<>::do_get_monthname): Use it.
+       * config/abi/pre/gnu.ver: Export new symbols.
+       * doc/xml/manual/prerequisites.xml: Add ru_RU.UTF-8 and
+       ru_RU.ISO-8859-5.
+       * testsuite/lib/libstdc++.exp: Adjust.
+       * testsuite/22_locale/time_get/get_weekday/char/38081-1.cc: New.
+       * testsuite/22_locale/time_get/get_weekday/char/38081-2.cc: Likewise.
+
 2010-01-05  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * configure: Regenerate.
index 2d4b0c3..c678984 100644 (file)
@@ -1,6 +1,6 @@
 ## Linker script for GNU versioning (GNU ld 2.13.91+ only.)
 ##
-## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 ## Free Software Foundation, Inc.
 ##
 ## This file is part of the GNU ISO C++ Library.  This library is free
@@ -149,7 +149,7 @@ GLIBCXX_3.4 {
       std::th[a-h]*;
       std::th[j-q]*;
       std::th[s-z]*;
-      std::t[i-n]*;
+#     std::t[i-n]*;
       std::tr1::h[^a]*;
       std::t[s-z]*;
 #     std::[A-Zu-z]*;
@@ -459,6 +459,21 @@ GLIBCXX_3.4 {
     # std::money_put
     _ZNKSt9money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE*;
 
+    # std::time_get
+    _ZNSt8time_get*;
+    _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[0-9]*;
+    _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE1[0-9]*;
+
+    # std::time_get_byname
+    _ZNSt15time_get_byname*;
+    
+    # std::time_put
+    _ZNSt8time_put*;
+    _ZNKSt8time_put*;
+
+    # std::time_put_byname
+    _ZNSt15time_put_byname*;
+
     # std::numeric_limits
     _ZNSt14numeric_limitsI[^g]E*;
 
@@ -1081,6 +1096,9 @@ GLIBCXX_3.4.14 {
 
     _ZSt25__throw_bad_function_callv;
 
+    # std::time_get::_M_extract_wday_or_month
+    _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE24_M_extract_wday_or_month*;
+
 } GLIBCXX_3.4.13;
 
 # Symbols in the support library (libsupc++) have their own tag.
index 20a0478..6a55e0c 100644 (file)
@@ -86,6 +86,8 @@ fr_FR@euro          ISO-8859-15
 is_IS               UTF-8
 it_IT               ISO-8859-1
 ja_JP.eucjp         EUC-JP
+ru_RU.ISO-8859-5    ISO-8859-5
+ru_RU.UTF-8         UTF-8
 se_NO.UTF-8         UTF-8
 ta_IN               UTF-8
 zh_TW               BIG5
index e151828..525a533 100644 (file)
@@ -1,6 +1,6 @@
 // Locale support -*- C++ -*-
 
-// Copyright (C) 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 2010 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
@@ -652,13 +652,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                     int __min, int __max, size_t __len,
                     ios_base& __io, ios_base::iostate& __err) const;
 
-      // Extract day or month name, or any unique array of string
-      // literals in a const _CharT* array.
+      // Extract any unique array of string literals in a const _CharT* array.
       iter_type
       _M_extract_name(iter_type __beg, iter_type __end, int& __member,
                      const _CharT** __names, size_t __indexlen,
                      ios_base& __io, ios_base::iostate& __err) const;
 
+      // Extract day or month name in a const _CharT* array.
+      iter_type
+      _M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member,
+                              const _CharT** __names, size_t __indexlen,
+                              ios_base& __io, ios_base::iostate& __err) const;
+
       // Extract on a component-by-component basis, via __format argument.
       iter_type
       _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
index 96feeaf..73cd747 100644 (file)
@@ -1,6 +1,6 @@
 // Locale support -*- C++ -*-
 
-// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 2010 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
@@ -950,6 +950,77 @@ _GLIBCXX_END_LDBL_NAMESPACE
   template<typename _CharT, typename _InIter>
     _InIter
     time_get<_CharT, _InIter>::
+    _M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member,
+                            const _CharT** __names, size_t __indexlen,
+                            ios_base& __io, ios_base::iostate& __err) const
+    {
+      typedef char_traits<_CharT>              __traits_type;
+      const locale& __loc = __io._M_getloc();
+      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+
+      int* __matches = static_cast<int*>(__builtin_alloca(2 * sizeof(int)
+                                                         * __indexlen));
+      size_t __nmatches = 0;
+      size_t* __matches_lengths = 0;
+      size_t __pos = 0;
+
+      if (__beg != __end)
+       {
+         const char_type __c = *__beg;
+         for (size_t __i = 0; __i < 2 * __indexlen; ++__i)
+           if (__c == __names[__i][0]
+               || __c == __ctype.toupper(__names[__i][0]))
+             __matches[__nmatches++] = __i;
+       }
+
+      if (__nmatches)
+       {
+         ++__beg, ++__pos;
+
+         __matches_lengths
+           = static_cast<size_t*>(__builtin_alloca(sizeof(size_t)
+                                                   * __nmatches));
+         for (size_t __i = 0; __i < __nmatches; ++__i)
+           __matches_lengths[__i]
+             = __traits_type::length(__names[__matches[__i]]);
+       }
+
+      for (; __beg != __end; ++__beg, ++__pos)
+       {
+         size_t __nskipped = 0;
+         const char_type __c = *__beg;
+         for (size_t __i = 0; __i < __nmatches;)
+           {
+             const char_type* __name = __names[__matches[__i]];
+             if (__pos >= __matches_lengths[__i])
+               ++__nskipped, ++__i;
+             else if (!(__name[__pos] == __c))
+               {
+                 --__nmatches;
+                 __matches[__i] = __matches[__nmatches];
+                 __matches_lengths[__i] = __matches_lengths[__nmatches];
+               }
+             else
+               ++__i;
+           }
+         if (__nskipped == __nmatches)
+           break;
+       }
+
+      if ((__nmatches == 1 && __matches_lengths[0] == __pos)
+         || (__nmatches == 2 && (__matches_lengths[0] == __pos
+                                 || __matches_lengths[1] == __pos)))
+       __member = (__matches[0] >= __indexlen
+                   ? __matches[0] - __indexlen : __matches[0]);
+      else
+       __err |= ios_base::failbit;
+
+      return __beg;
+    }
+
+  template<typename _CharT, typename _InIter>
+    _InIter
+    time_get<_CharT, _InIter>::
     do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
                ios_base::iostate& __err, tm* __tm) const
     {
@@ -991,35 +1062,14 @@ _GLIBCXX_END_LDBL_NAMESPACE
       const locale& __loc = __io._M_getloc();
       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
-      const char_type*  __days[7];
+      const char_type* __days[14];
       __tp._M_days_abbreviated(__days);
+      __tp._M_days(__days + 7);
       int __tmpwday;
       ios_base::iostate __tmperr = ios_base::goodbit;
-      __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7,
-                             __io, __tmperr);
-
-      // Check to see if non-abbreviated name exists, and extract.
-      // NB: Assumes both _M_days and _M_days_abbreviated organized in
-      // exact same order, first to last, such that the resulting
-      // __days array with the same index points to a day, and that
-      // day's abbreviated form.
-      // NB: Also assumes that an abbreviated name is a subset of the name.
-      if (!__tmperr && __beg != __end)
-       {
-         size_t __pos = __traits_type::length(__days[__tmpwday]);
-         __tp._M_days(__days);
-         const char_type* __name = __days[__tmpwday];
-         if (__name[__pos] == *__beg)
-           {
-             // Extract the rest of it.
-             const size_t __len = __traits_type::length(__name);
-             while (__pos < __len && __beg != __end
-                    && __name[__pos] == *__beg)
-               ++__beg, ++__pos;
-             if (__len != __pos)
-               __tmperr |= ios_base::failbit;
-           }
-       }
+
+      __beg = _M_extract_wday_or_month(__beg, __end, __tmpwday, __days, 7,
+                                      __io, __tmperr);
       if (!__tmperr)
        __tm->tm_wday = __tmpwday;
       else
@@ -1040,35 +1090,14 @@ _GLIBCXX_END_LDBL_NAMESPACE
       const locale& __loc = __io._M_getloc();
       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
-      const char_type*  __months[12];
+      const char_type*  __months[24];
       __tp._M_months_abbreviated(__months);
+      __tp._M_months(__months + 12);
       int __tmpmon;
       ios_base::iostate __tmperr = ios_base::goodbit;
-      __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, 
-                             __io, __tmperr);
-
-      // Check to see if non-abbreviated name exists, and extract.
-      // NB: Assumes both _M_months and _M_months_abbreviated organized in
-      // exact same order, first to last, such that the resulting
-      // __months array with the same index points to a month, and that
-      // month's abbreviated form.
-      // NB: Also assumes that an abbreviated name is a subset of the name.
-      if (!__tmperr && __beg != __end)
-       {
-         size_t __pos = __traits_type::length(__months[__tmpmon]);
-         __tp._M_months(__months);
-         const char_type* __name = __months[__tmpmon];
-         if (__name[__pos] == *__beg)
-           {
-             // Extract the rest of it.
-             const size_t __len = __traits_type::length(__name);
-             while (__pos < __len && __beg != __end
-                    && __name[__pos] == *__beg)
-               ++__beg, ++__pos;
-             if (__len != __pos)
-               __tmperr |= ios_base::failbit;
-           }
-       }
+
+      __beg = _M_extract_wday_or_month(__beg, __end, __tmpmon, __months, 12,
+                                      __io, __tmperr);
       if (!__tmperr)
        __tm->tm_mon = __tmpmon;
       else
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_weekday/char/38081-1.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_weekday/char/38081-1.cc
new file mode 100644 (file)
index 0000000..e237dcc
--- /dev/null
@@ -0,0 +1,86 @@
+// { dg-require-namedlocale "" }
+
+// 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 <cstring>
+#include <testsuite_hooks.h>
+
+// libstdc++/38081
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  typedef istreambuf_iterator<char> iterator_type;
+
+  // basic construction
+  locale loc("ru_RU.ISO-8859-5");
+
+  // create an ostream-derived object, cache the time_get facet
+  iterator_type end;
+
+  istringstream iss;
+  iss.imbue(loc);
+  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;
+
+  // iter_type 
+  // get_weekday(iter_type, iter_type, ios_base&, 
+  //             ios_base::iostate&, tm*) const
+
+  iss.str("\xbf\xdd\xd4");
+  iterator_type is_it01(iss);
+  tm time01;
+  memset(&time01, -1, sizeof(tm));
+  errorstate = good;
+  tim_get.get_weekday(is_it01, end, iss, errorstate, &time01);
+  VERIFY( time01.tm_wday == 1 );
+  VERIFY( errorstate == ios_base::eofbit );
+
+  iss.str("\xbf\xde\xdd\xd5\xd4\xd5\xdb\xec\xdd\xd8\xda");
+  iterator_type is_it02(iss);
+  tm time02;
+  memset(&time02, -1, sizeof(tm));
+  errorstate = good;
+  tim_get.get_weekday(is_it02, end, iss, errorstate, &time02);
+  VERIFY( time02.tm_wday == 1 );
+  VERIFY( errorstate == ios_base::eofbit );
+
+  iss.str("\xbf\xdd\xd4\xd5\xd4\xd5\xdb\xec\xdd\xd8\xda");
+  iterator_type is_it03(iss);
+  tm time03;
+  memset(&time03, -1, sizeof(tm));
+  errorstate = good;
+  iterator_type ret = tim_get.get_weekday(is_it03, end, iss,
+                                         errorstate, &time03);
+  VERIFY( time03.tm_wday == 1 );
+  VERIFY( errorstate == ios_base::goodbit );
+  VERIFY( *ret == '\xd5' );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_weekday/char/38081-2.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_weekday/char/38081-2.cc
new file mode 100644 (file)
index 0000000..6f88068
--- /dev/null
@@ -0,0 +1,98 @@
+// 2010-01-05  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 <cstring>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  typedef istreambuf_iterator<char> iterator_type;
+
+  // basic construction
+  locale loc("ru_RU.UTF8");
+
+  // create an ostream-derived object, cache the time_get facet
+  iterator_type end;
+
+  istringstream iss;
+  iss.imbue(loc);
+  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;
+
+  // iter_type 
+  // get_weekday(iter_type, iter_type, ios_base&, 
+  //             ios_base::iostate&, tm*) const
+
+  const char* awdays[7] = { "\u0412\u0441\u043A",
+                           "\u041F\u043D\u0434",
+                           "\u0412\u0442\u0440",
+                           "\u0421\u0440\u0434",
+                           "\u0427\u0442\u0432",
+                           "\u041F\u0442\u043D",
+                           "\u0421\u0431\u0442" };
+
+  for (unsigned i = 0; i < 7; ++i)
+    {
+      iss.str(awdays[i]);
+      iterator_type is_it01(iss);
+      tm time01;
+      memset(&time01, -1, sizeof(tm));
+      errorstate = good;
+      tim_get.get_weekday(is_it01, end, iss, errorstate, &time01);
+      VERIFY( time01.tm_wday == i );
+      VERIFY( errorstate == ios_base::eofbit );
+    }
+
+  const char* wdays[7] = { "\u0412\u043E\u0441\u043A\u0440\u0435"
+                          "\u0441\u0435\u043D\u044C\u0435",
+                          "\u041F\u043E\u043D\u0435\u0434\u0435"
+                          "\u043B\u044C\u043D\u0438\u043A",
+                          "\u0412\u0442\u043E\u0440\u043D\u0438\u043A",
+                          "\u0421\u0440\u0435\u0434\u0430",
+                          "\u0427\u0435\u0442\u0432\u0435\u0440\u0433",
+                          "\u041F\u044F\u0442\u043D\u0438\u0446\u0430",
+                          "\u0421\u0443\u0431\u0431\u043E\u0442\u0430" };
+
+  for (unsigned i = 0; i < 7; ++i)
+    {
+      iss.str(wdays[i]);
+      iterator_type is_it01(iss);
+      tm time01;
+      memset(&time01, -1, sizeof(tm));
+      errorstate = good;
+      tim_get.get_weekday(is_it01, end, iss, errorstate, &time01);
+      VERIFY( time01.tm_wday == i );
+      VERIFY( errorstate == ios_base::eofbit );
+    }
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
index ab4ab24..09cae6d 100644 (file)
@@ -1,6 +1,6 @@
 # libstdc++ "tool init file" for DejaGNU
 
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 # Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -883,6 +883,8 @@ proc check_v3_target_namedlocale { } {
        puts $f "     locale(\"is_IS.UTF-8\");"
        puts $f "     locale(\"it_IT\");"
        puts $f "     locale(\"ja_JP.eucjp\");"
+       puts $f "     locale(\"ru_RU.ISO-8859-5\");"
+       puts $f "     locale(\"ru_RU.UTF-8\");"
        puts $f "     locale(\"se_NO.UTF-8\");"
        puts $f "     locale(\"ta_IN\");"
        puts $f "     locale(\"zh_TW\");"