This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] libstdc++/21209


Hi,

tested x86-linux, committed to mainline.

Paolo.

////////////////
2005-04-26  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/21209
	* include/bits/locale_facets.tcc (_M_extract_int): Avoid signed
	integer overflow, always use a suited unsigned type in the main
	parsing loop.
	(struct __to_unsigned_type): New.
	* testsuite/22_locale/num_get/get/char/16.cc: New.
	* testsuite/22_locale/num_get/get/wchar_t/16.cc: Likewise.
diff -prN libstdc++-v3-orig/include/bits/locale_facets.tcc libstdc++-v3/include/bits/locale_facets.tcc
*** libstdc++-v3-orig/include/bits/locale_facets.tcc	Sun Apr 17 16:30:36 2005
--- libstdc++-v3/include/bits/locale_facets.tcc	Mon Apr 25 23:34:20 2005
*************** namespace std
*** 440,445 ****
--- 440,459 ----
        return __beg;
      }
  
+   template<typename _ValueT>
+     struct __to_unsigned_type
+     { typedef _ValueT __type; };
+ 
+   template<>
+     struct __to_unsigned_type<long>
+     { typedef unsigned long __type; };
+ 
+ #ifdef _GLIBCXX_USE_LONG_LONG
+   template<>
+     struct __to_unsigned_type<long long>
+     { typedef unsigned long long __type; };
+ #endif
+ 
    template<typename _CharT, typename _InIter>
      template<typename _ValueT>
        _InIter
*************** namespace std
*** 447,454 ****
        _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
  		     ios_base::iostate& __err, _ValueT& __v) const
        {
!         typedef char_traits<_CharT>			__traits_type;
! 	typedef typename numpunct<_CharT>::__cache_type __cache_type;
  	__use_cache<__cache_type> __uc;
  	const locale& __loc = __io._M_getloc();
  	const __cache_type* __lc = __uc(__loc);
--- 461,469 ----
        _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
  		     ios_base::iostate& __err, _ValueT& __v) const
        {
!         typedef char_traits<_CharT>			     __traits_type;
! 	typedef typename __to_unsigned_type<_ValueT>::__type __unsigned_type;	
! 	typedef typename numpunct<_CharT>::__cache_type      __cache_type;
  	__use_cache<__cache_type> __uc;
  	const locale& __loc = __io._M_getloc();
  	const __cache_type* __lc = __uc(__loc);
*************** namespace std
*** 536,638 ****
  	  __found_grouping.reserve(32);
  	int __sep_pos = 0;
  	bool __overflow = false;
! 	_ValueT __result = 0;
  	const char_type* __q;
  	const char_type* __lit_zero = __lit + __num_base::_S_izero;
! 	if (__negative)
  	  {
! 	    const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
! 	    while (!__testeof)
  	      {
! 		// According to 22.2.2.1.2, p8-9, first look for thousands_sep
! 		// and decimal_point.
! 		if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  		  {
! 		    // NB: Thousands separator at the beginning of a string
! 		    // is a no-no, as is two consecutive thousands separators.
! 		    if (__sep_pos)
! 		      {
! 			__found_grouping += static_cast<char>(__sep_pos);
! 			__sep_pos = 0;
! 		      }
! 		    else
! 		      {
! 			__err |= ios_base::failbit;
! 			break;
! 		      }
  		  }
! 		else if (__c == __lc->_M_decimal_point)
! 		  break;
! 		else if ((__q = __traits_type::find(__lit_zero, __len, __c)))
  		  {
! 		    int __digit = __q - __lit_zero;
! 		    if (__digit > 15)
! 		      __digit -= 6;
! 		    if (__result < __min)
! 		      __overflow = true;
! 		    else
! 		      {
! 			const _ValueT __new_result = (__result * __base
! 						      - __digit);
! 			__overflow |= __new_result > __result;
! 			__result = __new_result;
! 			++__sep_pos;
! 		      }
  		  }
- 		else
- 		  // Not a valid input item.
- 		  break;
- 
- 		if (++__beg != __end)
- 		  __c = *__beg;
- 		else
- 		  __testeof = true;
  	      }
! 	  }
! 	else
! 	  {
! 	    const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
! 	    while (!__testeof)
  	      {
! 		if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
! 		  {
! 		    if (__sep_pos)
! 		      {
! 			__found_grouping += static_cast<char>(__sep_pos);
! 			__sep_pos = 0;
! 		      }
! 		    else
! 		      {
! 			__err |= ios_base::failbit;
! 			break;
! 		      }
! 		  }
! 		else if (__c == __lc->_M_decimal_point)
! 		  break;
! 		else if ((__q = __traits_type::find(__lit_zero, __len, __c)))
  		  {
! 		    int __digit = __q - __lit_zero;
! 		    if (__digit > 15)
! 		      __digit -= 6;
! 		    if (__result > __max)
! 		      __overflow = true;
! 		    else
! 		      {
! 			const _ValueT __new_result = (__result * __base
! 						      + __digit);
! 			__overflow |= __new_result < __result;
! 			__result = __new_result;
! 			++__sep_pos;
! 		      }
  		  }
- 		else
- 		  break;
- 
- 		if (++__beg != __end)
- 		  __c = *__beg;
- 		else
- 		  __testeof = true;
  	      }
  	  }
  
  	// Digit grouping is checked. If grouping and found_grouping don't
--- 551,606 ----
  	  __found_grouping.reserve(32);
  	int __sep_pos = 0;
  	bool __overflow = false;
! 	const __unsigned_type __max = __negative ?
! 	  -numeric_limits<_ValueT>::min() : numeric_limits<_ValueT>::max();
! 	const __unsigned_type __smax = __max / __base;
! 	__unsigned_type __result = 0;
  	const char_type* __q;
  	const char_type* __lit_zero = __lit + __num_base::_S_izero;
! 	while (!__testeof)
  	  {
! 	    // According to 22.2.2.1.2, p8-9, first look for thousands_sep
! 	    // and decimal_point.
! 	    if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  	      {
! 		// NB: Thousands separator at the beginning of a string
! 		// is a no-no, as is two consecutive thousands separators.
! 		if (__sep_pos)
  		  {
! 		    __found_grouping += static_cast<char>(__sep_pos);
! 		    __sep_pos = 0;
  		  }
! 		else
  		  {
! 		    __err |= ios_base::failbit;
! 		    break;
  		  }
  	      }
! 	    else if (__c == __lc->_M_decimal_point)
! 	      break;
! 	    else if ((__q = __traits_type::find(__lit_zero, __len, __c)))
  	      {
! 		int __digit = __q - __lit_zero;
! 		if (__digit > 15)
! 		  __digit -= 6;
! 		if (__result > __smax)
! 		  __overflow = true;
! 		else
  		  {
! 		    __result *= __base;
! 		    __overflow |= __result > __max - __digit;
! 		    __result += __digit;
! 		    ++__sep_pos;
  		  }
  	      }
+ 	    else
+ 	      // Not a valid input item.	      
+ 	      break;
+ 	    
+ 	    if (++__beg != __end)
+ 	      __c = *__beg;
+ 	    else
+ 	      __testeof = true;
  	  }
  
  	// Digit grouping is checked. If grouping and found_grouping don't
*************** namespace std
*** 650,656 ****
  
  	if (!(__err & ios_base::failbit) && !__overflow
  	    && (__sep_pos || __found_zero || __found_grouping.size()))
! 	  __v = __result;
  	else
  	  __err |= ios_base::failbit;
  
--- 618,624 ----
  
  	if (!(__err & ios_base::failbit) && !__overflow
  	    && (__sep_pos || __found_zero || __found_grouping.size()))
! 	  __v = __negative ? -__result : __result;
  	else
  	  __err |= ios_base::failbit;
  
diff -prN libstdc++-v3-orig/testsuite/22_locale/num_get/get/char/16.cc libstdc++-v3/testsuite/22_locale/num_get/get/char/16.cc
*** libstdc++-v3-orig/testsuite/22_locale/num_get/get/char/16.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/testsuite/22_locale/num_get/get/char/16.cc	Tue Apr 26 00:33:14 2005
***************
*** 0 ****
--- 1,202 ----
+ // 2005-04-26  Paolo Carlini  <pcarlini@suse.de>
+ 
+ // Copyright (C) 2005 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 <limits>
+ #include <testsuite_hooks.h>
+ 
+ void test01()
+ {
+   using namespace std;
+   typedef istreambuf_iterator<char> iterator_type;
+   
+   bool test __attribute__((unused)) = true;
+ 
+   stringstream ss;
+   const num_get<char>& ng = use_facet<num_get<char> >(ss.getloc()); 
+   ios_base::iostate err;
+   iterator_type end;
+ 
+   unsigned short us0, us1 = numeric_limits<unsigned short>::max();
+   unsigned int ui0, ui1 = numeric_limits<unsigned int>::max();
+   unsigned long ul0, ul1 = numeric_limits<unsigned long>::max();
+   long l01, l1 = numeric_limits<long>::max();
+   long l02, l2 = numeric_limits<long>::min();
+ #ifdef _GLIBCXX_USE_LONG_LONG
+   unsigned long long ull0, ull1 = numeric_limits<unsigned long long>::max();
+   long long ll01, ll1 = numeric_limits<long long>::max();
+   long long ll02, ll2 = numeric_limits<long long>::min();
+ #endif
+ 
+   const string empty;
+ 
+   us0 = 0;
+   ss << us1;
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, us0);
+   VERIFY( err == ios_base::eofbit );
+   VERIFY( us0 == us1 );
+ 
+   us0 = 0;
+   ss.clear();
+   ss.str(empty);
+   ss << us1 << '0';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, us0);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( us0 == 0 );
+ 
+   ui0 = 0U;
+   ss.clear();
+   ss.str(empty);
+   ss << ui1 << ' ';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ui0);
+   VERIFY( err == ios_base::goodbit );
+   VERIFY( ui0 == ui1 );
+ 
+   ui0 = 0U;
+   ss.clear();
+   ss.str(empty);
+   ss << ui1 << '1';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ui0);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( ui0 == 0U );
+ 
+   ul0 = 0UL;
+   ss.clear();
+   ss.str(empty);
+   ss << ul1;
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+   VERIFY( err == ios_base::eofbit );
+   VERIFY( ul0 == ul1 );
+ 
+   ul0 = 0UL;
+   ss.clear();
+   ss.str(empty);
+   ss << ul1 << '2';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( ul0 == 0UL );
+ 
+   l01 = 0L;
+   ss.clear();
+   ss.str(empty);
+   ss << l1 << ' ';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, l01);
+   VERIFY( err == ios_base::goodbit );
+   VERIFY( l01 == l1 );
+ 
+   l01 = 0L;
+   ss.clear();
+   ss.str(empty);
+   ss << l1 << '3';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, l01);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( l01 == 0L );
+ 
+   l02 = 0L;
+   ss.clear();
+   ss.str(empty);
+   ss << l2;
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, l02);
+   VERIFY( err == ios_base::eofbit );
+   VERIFY( l02 == l2 );
+ 
+   l02 = 0L;
+   ss.clear();
+   ss.str(empty);
+   ss << l2 << '4';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, l02);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( l02 == 0L );
+ 
+ #ifdef _GLIBCXX_USE_LONG_LONG
+   ull0 = 0ULL;
+   ss.clear();
+   ss.str(empty);
+   ss << ull1 << ' ';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ull0);
+   VERIFY( err == ios_base::goodbit );
+   VERIFY( ull0 == ull1 );
+ 
+   ull0 = 0ULL;
+   ss.clear();
+   ss.str(empty);
+   ss << ull1 << '5';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ull0);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( ull0 == 0ULL );
+ 
+   ll01 = 0LL;
+   ss.clear();
+   ss.str(empty);
+   ss << ll1;
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ll01);
+   VERIFY( err == ios_base::eofbit );
+   VERIFY( ll01 == ll1 );
+ 
+   ll01 = 0LL;
+   ss.clear();
+   ss.str(empty);
+   ss << ll1 << '6';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ll01);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( ll01 == 0LL );
+ 
+   ll02 = 0LL;
+   ss.clear();
+   ss.str(empty);
+   ss << ll2 << ' ';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ll02);
+   VERIFY( err == ios_base::goodbit );
+   VERIFY( ll02 == ll2 );
+ 
+   ll02 = 0LL;
+   ss.clear();
+   ss.str(empty);
+   ss << ll2 << '7';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ll02);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( ll02 == 0LL );
+ #endif
+ }
+ 
+ int main()
+ {
+   test01();
+   return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/22_locale/num_get/get/wchar_t/16.cc libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/16.cc
*** libstdc++-v3-orig/testsuite/22_locale/num_get/get/wchar_t/16.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/16.cc	Tue Apr 26 00:32:53 2005
***************
*** 0 ****
--- 1,202 ----
+ // 2005-04-26  Paolo Carlini  <pcarlini@suse.de>
+ 
+ // Copyright (C) 2005 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 <limits>
+ #include <testsuite_hooks.h>
+ 
+ void test01()
+ {
+   using namespace std;
+   typedef istreambuf_iterator<wchar_t> iterator_type;
+   
+   bool test __attribute__((unused)) = true;
+ 
+   wstringstream ss;
+   const num_get<wchar_t>& ng = use_facet<num_get<wchar_t> >(ss.getloc()); 
+   ios_base::iostate err;
+   iterator_type end;
+ 
+   unsigned short us0, us1 = numeric_limits<unsigned short>::max();
+   unsigned int ui0, ui1 = numeric_limits<unsigned int>::max();
+   unsigned long ul0, ul1 = numeric_limits<unsigned long>::max();
+   long l01, l1 = numeric_limits<long>::max();
+   long l02, l2 = numeric_limits<long>::min();
+ #ifdef _GLIBCXX_USE_LONG_LONG
+   unsigned long long ull0, ull1 = numeric_limits<unsigned long long>::max();
+   long long ll01, ll1 = numeric_limits<long long>::max();
+   long long ll02, ll2 = numeric_limits<long long>::min();
+ #endif
+ 
+   const wstring empty;
+ 
+   us0 = 0;
+   ss << us1;
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, us0);
+   VERIFY( err == ios_base::eofbit );
+   VERIFY( us0 == us1 );
+ 
+   us0 = 0;
+   ss.clear();
+   ss.str(empty);
+   ss << us1 << L'0';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, us0);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( us0 == 0 );
+ 
+   ui0 = 0U;
+   ss.clear();
+   ss.str(empty);
+   ss << ui1 << ' ';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ui0);
+   VERIFY( err == ios_base::goodbit );
+   VERIFY( ui0 == ui1 );
+ 
+   ui0 = 0U;
+   ss.clear();
+   ss.str(empty);
+   ss << ui1 << L'1';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ui0);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( ui0 == 0U );
+ 
+   ul0 = 0UL;
+   ss.clear();
+   ss.str(empty);
+   ss << ul1;
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+   VERIFY( err == ios_base::eofbit );
+   VERIFY( ul0 == ul1 );
+ 
+   ul0 = 0UL;
+   ss.clear();
+   ss.str(empty);
+   ss << ul1 << L'2';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( ul0 == 0UL );
+ 
+   l01 = 0L;
+   ss.clear();
+   ss.str(empty);
+   ss << l1 << L' ';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, l01);
+   VERIFY( err == ios_base::goodbit );
+   VERIFY( l01 == l1 );
+ 
+   l01 = 0L;
+   ss.clear();
+   ss.str(empty);
+   ss << l1 << L'3';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, l01);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( l01 == 0L );
+ 
+   l02 = 0L;
+   ss.clear();
+   ss.str(empty);
+   ss << l2;
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, l02);
+   VERIFY( err == ios_base::eofbit );
+   VERIFY( l02 == l2 );
+ 
+   l02 = 0L;
+   ss.clear();
+   ss.str(empty);
+   ss << l2 << L'4';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, l02);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( l02 == 0L );
+ 
+ #ifdef _GLIBCXX_USE_LONG_LONG
+   ull0 = 0ULL;
+   ss.clear();
+   ss.str(empty);
+   ss << ull1 << L' ';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ull0);
+   VERIFY( err == ios_base::goodbit );
+   VERIFY( ull0 == ull1 );
+ 
+   ull0 = 0ULL;
+   ss.clear();
+   ss.str(empty);
+   ss << ull1 << L'5';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ull0);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( ull0 == 0ULL );
+ 
+   ll01 = 0LL;
+   ss.clear();
+   ss.str(empty);
+   ss << ll1;
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ll01);
+   VERIFY( err == ios_base::eofbit );
+   VERIFY( ll01 == ll1 );
+ 
+   ll01 = 0LL;
+   ss.clear();
+   ss.str(empty);
+   ss << ll1 << L'6';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ll01);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( ll01 == 0LL );
+ 
+   ll02 = 0LL;
+   ss.clear();
+   ss.str(empty);
+   ss << ll2 << L' ';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ll02);
+   VERIFY( err == ios_base::goodbit );
+   VERIFY( ll02 == ll2 );
+ 
+   ll02 = 0LL;
+   ss.clear();
+   ss.str(empty);
+   ss << ll2 << L'7';
+   err = ios_base::goodbit;
+   end = ng.get(ss.rdbuf(), 0, ss, err, ll02);
+   VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
+   VERIFY( ll02 == 0LL );
+ #endif
+ }
+ 
+ int main()
+ {
+   test01();
+   return 0;
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]