This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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++/5280



This patch fixes a problem that Peter Schmid noticed in libstdc++/5280.

The problem is pretty simple: libstdc++ uses "C" library functions
that depend on LANG == "C", namely strtold, strtod, sprintf, etc. In
particular, there is a dependence on the thousands_sep to be '.' in
many parts of the underlying locale parsing code.

I've abstracted out all these calls. Where possible, "C"
locale-specific functions are used. When not possible, setlocale
forces the issue...

The following patch includes an audit of all the facets for similar
issues. 

I'd be lying if I felt that this is a nice solution. I'm not
especially happy with it, and am contimplating replacing these "C"
library functions outright. I'd prefer not to do this right now, but
it's pretty easy to put in a better solution at a later date.

I believe this patch should go in first, then this other bit can go in
later, as specializations of __convert_to_v and __convert_from_v.


tested x86-linux, generic
tested x86-linux, gnu

2002-01-22  Benjamin Kosnik  <bkoz@redhat.com>

	Audit for LANG independence.
	* include/bits/localefwd.h: Tweaks.
	* include/bits/locale_facets.tcc (money_get::do_get(long double)):
	Use __convert_to_v.
	(time_get::do_get_year): Same.
	(__convert_from_v): Add.
	(num_put::_M_convert_float): Use.
	(num_put::_M_convert_int): Same.
	(money_put::do_put): Same.
	
	* src/locale-inst.cc: Add instantiations for __convert_from_v.
	* config/locale/time_members_gnu.cc: Cleanup setlocale usage.
	* config/locale/time_members_generic.cc: 
	* config/locale/messages_members_gnu.cc: Same.
	* config/locale/messages_members_gnu.h: Same.
	
	* testsuite/22_locale/codecvt_members_wchar_t_char.cc (test02): New.
	* testsuite/22_locale/codecvt_members_char_char.cc (test02): New.
	* testsuite/22_locale/collate_members_wchar_t.cc (test02): New.
	* testsuite/22_locale/collate_members_char.cc (test02): New.
	* testsuite/22_locale/ctype_members_wchar_t.cc (test03): New.
	* testsuite/22_locale/ctype_members_char.cc (test03): New.
	* testsuite/22_locale/messages_members_char.cc (test02): New.
	* testsuite/22_locale/moneypunct_members_wchar_t.cc (test02): New.
	* testsuite/22_locale/moneypunct_members_char.cc (test02): New.
	* testsuite/22_locale/money_get_members_wchar_t.cc (test04): New.
	* testsuite/22_locale/money_get_members_char.cc (test04): New.
	* testsuite/22_locale/money_put_members_wchar_t.cc (test04): New.
	* testsuite/22_locale/money_put_members_char.cc (test04): New.
	* testsuite/22_locale/numpunct_members_wchar_t.cc (test02): New.
	* testsuite/22_locale/numpunct_members_char.cc (test02): New.
	* testsuite/22_locale/time_put_members_wchar_t.cc (test03): New.
	* testsuite/22_locale/time_put_members_char.cc (test03): New.
	* testsuite/22_locale/time_get_members_wchar_t.cc (test07): New.
	* testsuite/22_locale/time_get_members_char.cc (test07): New.
	* testsuite/22_locale/num_get_members_wchar_t.cc (test03): New.
	* testsuite/22_locale/num_get_members_char.cc (test03): New.
	* testsuite/22_locale/num_put_members_wchar_t.cc (test03): New.
	* testsuite/22_locale/num_put_members_char.cc (test03): New.

	* testsuite/22_locale/time_get_members_char.cc: Fixups for global
	locale issues.
	* testsuite/22_locale/time_get_members_char.cc: Same.
	
2002-01-22  Benjamin Kosnik  <bkoz@redhat.com>

	libstdc++/5280
	* include/bits/localefwd.h: Tweak comments.
	* include/bits/locale_facets.h (__convert_to_v): Add.
	* include/bits/locale_facets.tcc (num_get::do_get(double)): Use it.
	(num_get::do_get(float)): Same.
	(num_get::do_get(long double)): Same.
	(num_get::do_get(bool)): Same.
	(num_get::do_get(long)): Same.
	(num_get::do_get(long long)): Same.
	(num_get::do_get(unsigned int)): Same.
	(num_get::do_get(unsigned short)): Same.
	(num_get::do_get(unsigned long)): Same.
	(num_get::do_get(unsigned long long)): Same.
	* config/locale/c_locale_gnu.cc (__convert_to_v): Specialize.
	* config/locale/c_locale_generic.cc: Same.
	
Index: config/locale/c_locale_generic.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/c_locale_generic.cc,v
retrieving revision 1.3
diff -c -p -r1.3 c_locale_generic.cc
*** c_locale_generic.cc	2001/12/15 07:05:03	1.3
--- c_locale_generic.cc	2002/01/22 20:43:06
***************
*** 37,42 ****
--- 37,199 ----
  
  namespace std 
  {
+   // Specializations for all types used in num_get.
+   template<>
+     void
+     __convert_to_v(const char* __s, long& __v, ios_base::iostate& __err, 
+ 		   const __c_locale&, int __base)
+     {
+       if (!(__err & ios_base::failbit))
+       {
+ 	char* __sanity;
+ 	errno = 0;
+ 	long __l = strtol(__s, &__sanity, __base);
+ 	if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	  __v = __l;
+ 	else
+ 	  __err |= ios_base::failbit;
+       }
+     }
+ 
+   template<>
+     void
+     __convert_to_v(const char* __s, unsigned long& __v, 
+ 		   ios_base::iostate& __err, const __c_locale&, int __base)
+     {
+       if (!(__err & ios_base::failbit))
+ 	{
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  unsigned long __ul = strtoul(__s, &__sanity, __base);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __ul;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	}
+     }
+ 
+ #ifdef _GLIBCPP_USE_LONG_LONG
+   template<>
+     void
+     __convert_to_v(const char* __s, long long& __v, ios_base::iostate& __err, 
+ 		   const __c_locale&, int __base)
+     {
+       if (!(__err & ios_base::failbit))
+ 	{
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  long long __ll = strtoll(__s, &__sanity, __base);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __ll;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	}
+     }
+ 
+   template<>
+     void
+     __convert_to_v(const char* __s, unsigned long long& __v, 
+ 		   ios_base::iostate& __err, const __c_locale&, int __base)
+     {
+       if (!(__err & ios_base::failbit))
+ 	{      
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  unsigned long long __ull = strtoull(__s, &__sanity, __base);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __ull;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	}  
+     }
+ #endif
+ 
+   template<>
+     void
+     __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 
+ 		   const __c_locale&, int) 	      
+     {
+       if (!(__err & ios_base::failbit))
+ 	{
+ 	  // Assumes __s formatted for "C" locale.
+ 	  const char* __old = setlocale(LC_ALL, "C");
+ 	  char* __sanity;
+ 	  errno = 0;
+ #ifdef _GLIBCPP_USE_C99
+ 	  float __f = strtof(__s, &__sanity);
+ #else
+ 	  float __f = static_cast<float>(strtod(__s, &__sanity));
+ #endif
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __f;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	  setlocale(LC_ALL, __old);
+ 	}
+     }
+ 
+   template<>
+     void
+     __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 
+ 		   const __c_locale&, int) 
+     {
+       if (!(__err & ios_base::failbit))
+ 	{
+ 	  // Assumes __s formatted for "C" locale.
+ 	  const char* __old = setlocale(LC_ALL, "C");
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  double __d = strtod(__s, &__sanity);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __d;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	  setlocale(LC_ALL, __old);
+ 	}
+     }
+ 
+   template<>
+     void
+     __convert_to_v(const char* __s, long double& __v, 
+ 		   ios_base::iostate& __err, const __c_locale&, int) 
+     {
+       if (!(__err & ios_base::failbit))
+ 	{
+ 	  // Assumes __s formatted for "C" locale.
+ 	  const char* __old = setlocale(LC_ALL, "C");
+ #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
+ 	  // Stage 2: Convert and store results.
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  long double __ld = strtold(__s, &__sanity);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __ld;
+ #else
+ 	  // Stage 2: Determine a conversion specifier.
+ 	  ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+ 	  const char* __conv;
+ 	  if (__basefield == ios_base::oct)
+ 	    __conv = "%Lo";
+ 	  else if (__basefield == ios_base::hex)
+ 	    __conv = "%LX";
+ 	  else if (__basefield == 0)
+ 	    __conv = "%Li";
+ 	  else
+ 	    __conv = "%Lf";
+ 
+ 	  // Stage 3: Store results.
+ 	  typedef typename char_traits<_CharT>::int_type int_type;
+ 	  long double __ld;
+ 	  int __p = sscanf(__s, __conv, &__ld);
+ 	  if (__p && static_cast<int_type>(__p) != char_traits<_CharT>::eof())
+ 	    __v = __ld;
+ #endif
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	  setlocale(LC_ALL, __old);
+ 	}
+     }
+ 
    void
    locale::facet::_S_create_c_locale(__c_locale& __cloc, const char*)
    { __cloc = NULL; }
Index: config/locale/c_locale_gnu.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/c_locale_gnu.cc,v
retrieving revision 1.6
diff -c -p -r1.6 c_locale_gnu.cc
*** c_locale_gnu.cc	2001/12/15 07:05:03	1.6
--- c_locale_gnu.cc	2002/01/22 20:43:07
***************
*** 39,44 ****
--- 39,168 ----
  
  namespace std 
  {
+   template<>
+     void
+     __convert_to_v(const char* __s, long& __v, ios_base::iostate& __err, 
+ 		   const __c_locale& __cloc, int __base)
+     {
+       if (!(__err & ios_base::failbit))
+       {
+ 	char* __sanity;
+ 	errno = 0;
+ 	long __l = __strtol_l(__s, &__sanity, __base, __cloc);
+ 	if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	  __v = __l;
+ 	else
+ 	  __err |= ios_base::failbit;
+       }
+     }
+ 
+   template<>
+     void
+     __convert_to_v(const char* __s, unsigned long& __v, 
+ 		   ios_base::iostate& __err, const __c_locale& __cloc, 
+ 		   int __base)
+     {
+       if (!(__err & ios_base::failbit))
+ 	{
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  unsigned long __ul = __strtoul_l(__s, &__sanity, __base, __cloc);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __ul;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	}
+     }
+ 
+ #ifdef _GLIBCPP_USE_LONG_LONG
+   template<>
+     void
+     __convert_to_v(const char* __s, long long& __v, ios_base::iostate& __err, 
+ 		   const __c_locale& __cloc, int __base)
+     {
+       if (!(__err & ios_base::failbit))
+ 	{
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  long long __ll = __strtoll_l(__s, &__sanity, __base, __cloc);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __ll;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	}
+     }
+ 
+   template<>
+     void
+     __convert_to_v(const char* __s, unsigned long long& __v, 
+ 		   ios_base::iostate& __err, const __c_locale& __cloc, 
+ 		   int __base)
+     {
+       if (!(__err & ios_base::failbit))
+ 	{      
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  unsigned long long __ull = __strtoull_l(__s, &__sanity, __base, 
+ 						  __cloc);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __ull;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	}  
+     }
+ #endif
+ 
+   template<>
+     void
+     __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 
+ 		   const __c_locale& __cloc, int)
+     {
+       if (!(__err & ios_base::failbit))
+ 	{
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  float __f = __strtof_l(__s, &__sanity, __cloc);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __f;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	}
+     }
+ 
+   template<>
+     void
+     __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 
+ 		   const __c_locale& __cloc, int)
+     {
+       if (!(__err & ios_base::failbit))
+ 	{
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  double __d = __strtod_l(__s, &__sanity, __cloc);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __d;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	}
+     }
+ 
+   template<>
+     void
+     __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
+ 		   const __c_locale& __cloc, int)
+     {
+       if (!(__err & ios_base::failbit))
+ 	{
+ 	  char* __sanity;
+ 	  errno = 0;
+ 	  long double __ld = __strtold_l(__s, &__sanity, __cloc);
+           if (__sanity != __s && *__sanity == '\0' && errno == 0)
+ 	    __v = __ld;
+ 	  else
+ 	    __err |= ios_base::failbit;
+ 	}
+     }
+ 
    void
    locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s)
    {
Index: config/locale/messages_members_gnu.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/messages_members_gnu.cc,v
retrieving revision 1.1
diff -c -p -r1.1 messages_members_gnu.cc
*** messages_members_gnu.cc	2001/08/08 02:48:58	1.1
--- messages_members_gnu.cc	2002/01/22 20:43:07
***************
*** 1,6 ****
  // std::messages implementation details, GNU version -*- C++ -*-
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // std::messages implementation details, GNU version -*- C++ -*-
  
! // Copyright (C) 2001, 2002 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
*************** namespace std
*** 49,56 ****
        uselocale(__old);
        return string(__msg);
  #else
!       setlocale(LC_ALL, _M_name_messages);
        const char* __msg = gettext(__dfault.c_str());
        return string(__msg);
  #endif
      }
--- 49,57 ----
        uselocale(__old);
        return string(__msg);
  #else
!       const char* __old = setlocale(LC_ALL, _M_name_messages);
        const char* __msg = gettext(__dfault.c_str());
+       setlocale(LC_ALL, __old);
        return string(__msg);
  #endif
      }
Index: config/locale/messages_members_gnu.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/messages_members_gnu.h,v
retrieving revision 1.3
diff -c -p -r1.3 messages_members_gnu.h
*** messages_members_gnu.h	2001/12/27 12:13:23	1.3
--- messages_members_gnu.h	2002/01/22 20:43:07
***************
*** 1,6 ****
  // std::messages implementation details, GNU version -*- C++ -*-
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // std::messages implementation details, GNU version -*- C++ -*-
  
! // Copyright (C) 2001, 2002 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
***************
*** 66,73 ****
        uselocale(__old);
        return _M_convert_from_char(__msg);
  #else
!       setlocale(LC_ALL, _M_name_messages);
        char* __msg = gettext(_M_convert_to_char(__dfault));
        return _M_convert_from_char(__msg);
  #endif
      }
--- 66,74 ----
        uselocale(__old);
        return _M_convert_from_char(__msg);
  #else
!       const char* __old = setlocale(LC_ALL, _M_name_messages);
        char* __msg = gettext(_M_convert_to_char(__dfault));
+       setlocale(LC_ALL, __old);
        return _M_convert_from_char(__msg);
  #endif
      }
Index: config/locale/numpunct_members_generic.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/numpunct_members_generic.cc,v
retrieving revision 1.1
diff -c -p -r1.1 numpunct_members_generic.cc
*** numpunct_members_generic.cc	2001/08/28 06:19:33	1.1
--- numpunct_members_generic.cc	2002/01/22 20:43:07
***************
*** 1,6 ****
  // std::numpunct implementation details, generic version -*- C++ -*-
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // std::numpunct implementation details, generic version -*- C++ -*-
  
! // Copyright (C) 2001, 2002 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
Index: config/locale/numpunct_members_gnu.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/numpunct_members_gnu.cc,v
retrieving revision 1.2
diff -c -p -r1.2 numpunct_members_gnu.cc
*** numpunct_members_gnu.cc	2001/11/28 07:40:12	1.2
--- numpunct_members_gnu.cc	2002/01/22 20:43:08
***************
*** 1,6 ****
  // std::numpunct implementation details, GNU version -*- C++ -*-
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // std::numpunct implementation details, GNU version -*- C++ -*-
  
! // Copyright (C) 2001, 2002 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
Index: config/locale/time_members_generic.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/time_members_generic.cc,v
retrieving revision 1.2
diff -c -p -r1.2 time_members_generic.cc
*** time_members_generic.cc	2001/10/02 18:44:36	1.2
--- time_members_generic.cc	2002/01/22 20:43:08
***************
*** 1,6 ****
  // std::time_get, std::time_put implementation, GNU version -*- C++ -*-
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // std::time_get, std::time_put implementation, GNU version -*- C++ -*-
  
! // Copyright (C) 2001, 2002 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
*************** namespace std
*** 44,51 ****
      _M_put_helper(char* __s, size_t __maxlen, const char* __format, 
  		  const tm* __tm) const
      {
!       setlocale(LC_ALL, _M_name_timepunct);
        strftime(__s, __maxlen, __format, __tm);
      }
  
    template<> 
--- 44,52 ----
      _M_put_helper(char* __s, size_t __maxlen, const char* __format, 
  		  const tm* __tm) const
      {
!       const char* __old = setlocale(LC_ALL, _M_name_timepunct);
        strftime(__s, __maxlen, __format, __tm);
+       setlocale(LC_ALL, __old);
      }
  
    template<> 
*************** namespace std
*** 117,124 ****
      _M_put_helper(wchar_t* __s, size_t __maxlen, const wchar_t* __format, 
  		  const tm* __tm) const
      {
!       setlocale(LC_ALL, _M_name_timepunct);
        wcsftime(__s, __maxlen, __format, __tm);
      }
  
    template<> 
--- 118,126 ----
      _M_put_helper(wchar_t* __s, size_t __maxlen, const wchar_t* __format, 
  		  const tm* __tm) const
      {
!       const char* __old = setlocale(LC_ALL, _M_name_timepunct);
        wcsftime(__s, __maxlen, __format, __tm);
+       setlocale(LC_ALL, __old);
      }
  
    template<> 
Index: config/locale/time_members_gnu.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/time_members_gnu.cc,v
retrieving revision 1.2
diff -c -p -r1.2 time_members_gnu.cc
*** time_members_gnu.cc	2001/10/02 18:44:36	1.2
--- time_members_gnu.cc	2002/01/22 20:43:09
***************
*** 1,6 ****
  // std::time_get, std::time_put implementation, GNU version -*- C++ -*-
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // std::time_get, std::time_put implementation, GNU version -*- C++ -*-
  
! // Copyright (C) 2001, 2002 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
*************** namespace std
*** 51,58 ****
        else
  	strftime(__s, __maxlen, __format, __tm);
  #else
!       setlocale(LC_ALL, _M_name_timepunct);
        strftime(__s, __maxlen, __format, __tm);
  #endif
      }
  
--- 51,59 ----
        else
  	strftime(__s, __maxlen, __format, __tm);
  #else
!       const char* __old = setlocale(LC_ALL, _M_name_timepunct);
        strftime(__s, __maxlen, __format, __tm);
+       setlocale(LC_ALL, __old);
  #endif
      }
  
*************** namespace std
*** 195,202 ****
        else
  	wcsftime(__s, __maxlen, __format, __tm);
  #else
!       setlocale(LC_ALL, _M_name_timepunct);
        wcsftime(__s, __maxlen, __format, __tm);
  #endif
      }
  
--- 196,204 ----
        else
  	wcsftime(__s, __maxlen, __format, __tm);
  #else
!       const char* __old = setlocale(LC_ALL, _M_name_timepunct);
        wcsftime(__s, __maxlen, __format, __tm);
+       setlocale(LC_ALL, __old);
  #endif
      }
  
Index: include/bits/locale_facets.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.38
diff -c -p -r1.38 locale_facets.h
*** locale_facets.h	2002/01/21 04:08:54	1.38
--- locale_facets.h	2002/01/22 20:43:14
***************
*** 1,6 ****
  // Locale support -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001 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
--- 1,7 ----
  // Locale support -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
! // 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
***************
*** 45,51 ****
  #ifdef _GLIBCPP_USE_WCHAR_T
  # include <cwctype>	// For wctype_t
  #endif 
! #include <ios>	// For ios_base
  
  namespace std
  {
--- 46,52 ----
  #ifdef _GLIBCPP_USE_WCHAR_T
  # include <cwctype>	// For wctype_t
  #endif 
! #include <ios>		// For ios_base
  
  namespace std
  {
*************** namespace std
*** 53,59 ****
    // Include host and configuration specific ctype enums for ctype_base.
    #include <bits/ctype_base.h>
  
!   // __ctype_abstract_base is the common base for ctype<_CharT>.  
    template<typename _CharT>
      class __ctype_abstract_base : public locale::facet, public ctype_base
      {
--- 54,60 ----
    // Include host and configuration specific ctype enums for ctype_base.
    #include <bits/ctype_base.h>
  
!   // Common base for ctype<_CharT>.  
    template<typename _CharT>
      class __ctype_abstract_base : public locale::facet, public ctype_base
      {
*************** namespace std
*** 417,425 ****
  
  
    // 22.2.2  The numeric category.
!   class __num_base
    {
!   public:
      // Used to establish gating factor for base 16 input.
      static const double _S_scale_hex;
      
--- 418,426 ----
  
  
    // 22.2.2  The numeric category.
!   class __num_base 
    {
!   protected:
      // Used to establish gating factor for base 16 input.
      static const double _S_scale_hex;
      
*************** namespace std
*** 438,443 ****
--- 439,445 ----
        _M_size = 21 + 1
      };
  
+     // num_put
      // Construct and return valid scanf format for floating point types.
      static bool
      _S_format_float(const ios_base& __io, char* __fptr, char __mod, 
*************** namespace std
*** 448,453 ****
--- 450,456 ----
      _S_format_int(const ios_base& __io, char* __fptr, char __mod, char __modl);
    };
  
+ 
    template<typename _CharT>
      class numpunct : public locale::facet
      {
*************** namespace std
*** 885,891 ****
  
    template<>
      size_t
!     collate<wchar_t>::_M_transform_helper(wchar_t*, const wchar_t*, 
  					  size_t) const;
  #endif
  
--- 888,894 ----
  
    template<>
      size_t
!     collate<wchar_t>::_M_transform_helper(wchar_t*, const wchar_t*,
  					  size_t) const;
  #endif
  
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.53
diff -c -p -r1.53 locale_facets.tcc
*** locale_facets.tcc	2002/01/16 00:51:44	1.53
--- locale_facets.tcc	2002/01/22 20:43:19
***************
*** 1,6 ****
  // Locale support -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001 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
--- 1,7 ----
  // Locale support -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
! // 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
***************
*** 39,47 ****
  #include <cctype>    // For isspace
  #include <limits>    // For numeric_limits
  #include <memory>    // For auto_ptr
! #include <bits/streambuf_iterator.h>     // For streambuf_iterators
! #include <typeinfo> 		// For bad_cast
  #include <vector>	
  
  namespace std
  {
--- 40,48 ----
  #include <cctype>    // For isspace
  #include <limits>    // For numeric_limits
  #include <memory>    // For auto_ptr
! #include <bits/streambuf_iterator.h>
  #include <vector>	
+ #include <typeinfo>  // For bad_cast.
  
  namespace std
  {
*************** namespace std
*** 87,92 ****
--- 88,94 ----
      }
  
  
+   // Stage 1: Determine a conversion specifier.
    template<typename _CharT, typename _InIter>
      _InIter
      num_get<_CharT, _InIter>::
*************** namespace std
*** 97,103 ****
        const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
        const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
  
!       // Check first for sign.
        const char_type __plus = __ctype.widen('+');
        const char_type __minus = __ctype.widen('-');
        int __pos = 0;
--- 99,105 ----
        const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
        const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
  
!       // First check for sign.
        const char_type __plus = __ctype.widen('+');
        const char_type __minus = __ctype.widen('-');
        int __pos = 0;
*************** namespace std
*** 216,221 ****
--- 218,224 ----
        return __beg;
      }
  
+   // Stage 1: Determine a conversion specifier.
    template<typename _CharT, typename _InIter>
      _InIter
      num_get<_CharT, _InIter>::
*************** namespace std
*** 227,233 ****
        const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
        const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
   
-       // Stage 1: determine a conversion specifier.
        // NB: Iff __basefield == 0, this can change based on contents.
        ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
        if (__basefield == ios_base::oct)
--- 230,235 ----
*************** namespace std
*** 381,393 ****
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, bool& __v) const
      {
!       // Parse bool values as long
        if (!(__io.flags() & ios_base::boolalpha))
          {
            // NB: We can't just call do_get(long) here, as it might
            // refer to a derived class.
  
-           // Stage 1: extract and determine the conversion specifier.
            // Assuming leading zeros eliminated, thus the size of 32 for
            // integral types
            char __xtrc[32];
--- 383,394 ----
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, bool& __v) const
      {
!       // Parse bool values as unsigned long
        if (!(__io.flags() & ios_base::boolalpha))
          {
            // NB: We can't just call do_get(long) here, as it might
            // refer to a derived class.
  
            // Assuming leading zeros eliminated, thus the size of 32 for
            // integral types
            char __xtrc[32];
*************** namespace std
*** 399,413 ****
            __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  				 numeric_limits<bool>::digits10 + 1, __base);
  
!           // Stage 2: convert and store results.
!           char* __sanity;
!           errno = 0;
!           long __l = strtol(__xtrc, &__sanity, __base);
!           if (!(__err & ios_base::failbit)
!               && __l <= 1
!               && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
!             __v = __l;
!           else
              __err |= ios_base::failbit;
          }
  
--- 400,410 ----
            __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  				 numeric_limits<bool>::digits10 + 1, __base);
  
! 	  unsigned long __ul; 
! 	  __convert_to_v(__xtrc, __ul, __err, _S_c_locale, __base);
! 	  if (!(__err & ios_base::failbit) && __ul <= 1)
! 	    __v = __ul;
! 	  else 
              __err |= ios_base::failbit;
          }
  
*************** namespace std
*** 415,421 ****
        else
          {
            locale __loc = __io.getloc();
! 	  const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__loc); 
            const char_type* __true = __np.truename().c_str();
            const char_type* __false = __np.falsename().c_str();
  
--- 412,418 ----
        else
          {
            locale __loc = __io.getloc();
! 	  const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 
            const char_type* __true = __np.truename().c_str();
            const char_type* __false = __np.falsename().c_str();
  
*************** namespace std
*** 456,478 ****
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, long& __v) const
      {
-       // Stage 1: extract and determine the conversion specifier.
        // Assuming leading zeros eliminated, thus the size of 32 for
        // integral types.
        char __xtrc[32];
        int __base;
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  			     numeric_limits<long>::digits10 + 1, __base);
! 
!       // Stage 2: convert and store results.
!       char* __sanity;
!       errno = 0;
!       long __l = strtol(__xtrc, &__sanity, __base);
!       if (!(__err & ios_base::failbit)
!           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
!         __v = __l;
!       else
!         __err |= ios_base::failbit;
        return __beg;
      }
  
--- 453,465 ----
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, long& __v) const
      {
        // Assuming leading zeros eliminated, thus the size of 32 for
        // integral types.
        char __xtrc[32];
        int __base;
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  			     numeric_limits<long>::digits10 + 1, __base);
!       __convert_to_v(__xtrc, __v, __err, _S_c_locale, __base);
        return __beg;
      }
  
*************** namespace std
*** 482,488 ****
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, unsigned short& __v) const
      {
-       // Stage 1: extract and determine the conversion specifier.
        // Assuming leading zeros eliminated, thus the size of 32 for
        // integral types.
        char __xtrc[32];
--- 469,474 ----
*************** namespace std
*** 490,506 ****
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  			     numeric_limits<unsigned short>::digits10 + 1,
  			     __base);
! 
!       // Stage 2: convert and store results.
!       char* __sanity;
!       errno = 0;
!       unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
!       if (!(__err & ios_base::failbit)
!           && __sanity != __xtrc && *__sanity == '\0' && errno == 0
!           && __ul <= USHRT_MAX)
!         __v = static_cast<unsigned short>(__ul);
!       else
!         __err |= ios_base::failbit;
        return __beg;
      }
  
--- 476,487 ----
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  			     numeric_limits<unsigned short>::digits10 + 1,
  			     __base);
!       unsigned long __ul;
!       __convert_to_v(__xtrc, __ul, __err, _S_c_locale, __base);
!       if (!(__err & ios_base::failbit) && __ul <= USHRT_MAX)
! 	__v = static_cast<unsigned short>(__ul);
!       else 
! 	__err |= ios_base::failbit;
        return __beg;
      }
  
*************** namespace std
*** 510,516 ****
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, unsigned int& __v) const
      {
-       // Stage 1: extract and determine the conversion specifier.
        // Assuming leading zeros eliminated, thus the size of 32 for
        // integral types.
        char __xtrc[32];
--- 491,496 ----
*************** namespace std
*** 518,534 ****
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  			     numeric_limits<unsigned int>::digits10 + 1,
  			     __base);
! 
!       // Stage 2: convert and store results.
!       char* __sanity;
!       errno = 0;
!       unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
!       if (!(__err & ios_base::failbit)
!           && __sanity != __xtrc && *__sanity == '\0' && errno == 0
!           && __ul <= UINT_MAX)
!         __v = static_cast<unsigned int>(__ul);
!       else
!         __err |= ios_base::failbit;
        return __beg;
      }
  
--- 498,509 ----
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  			     numeric_limits<unsigned int>::digits10 + 1,
  			     __base);
!       unsigned long __ul;
!       __convert_to_v(__xtrc, __ul, __err, _S_c_locale, __base);
!       if (!(__err & ios_base::failbit) && __ul <= UINT_MAX)
! 	__v = static_cast<unsigned int>(__ul);
!       else 
! 	__err |= ios_base::failbit;
        return __beg;
      }
  
*************** namespace std
*** 538,544 ****
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, unsigned long& __v) const
      {
-       // Stage 1: extract and determine the conversion specifier.
        // Assuming leading zeros eliminated, thus the size of 32 for
        // integral types.
        char __xtrc[32];
--- 513,518 ----
*************** namespace std
*** 546,561 ****
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  			     numeric_limits<unsigned long>::digits10 + 1,
  			     __base);
! 
!       // Stage 2: convert and store results.
!       char* __sanity;
!       errno = 0;
!       unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
!       if (!(__err & ios_base::failbit)
!           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
!         __v = __ul;
!       else
!         __err |= ios_base::failbit;
        return __beg;
      }
  
--- 520,526 ----
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  			     numeric_limits<unsigned long>::digits10 + 1,
  			     __base);
!       __convert_to_v(__xtrc, __v, __err, _S_c_locale, __base);
        return __beg;
      }
  
*************** namespace std
*** 566,588 ****
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, long long& __v) const
      {
-       // Stage 1: extract and determine the conversion specifier.
        // Assuming leading zeros eliminated, thus the size of 32 for
        // integral types.
        char __xtrc[32];
        int __base;
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  			     numeric_limits<long long>::digits10 + 1, __base);
! 
!       // Stage 2: convert and store results.
!       char* __sanity;
!       errno = 0;
!       long long __ll = strtoll(__xtrc, &__sanity, __base);
!       if (!(__err & ios_base::failbit)
!           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
!         __v = __ll;
!       else
!         __err |= ios_base::failbit;
        return __beg;
      }
  
--- 531,543 ----
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, long long& __v) const
      {
        // Assuming leading zeros eliminated, thus the size of 32 for
        // integral types.
        char __xtrc[32];
        int __base;
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, 
  			     numeric_limits<long long>::digits10 + 1, __base);
!       __convert_to_v(__xtrc, __v, __err, _S_c_locale, __base);
        return __beg;
      }
  
*************** namespace std
*** 592,598 ****
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, unsigned long long& __v) const
      {
-       // Stage 1: extract and determine the conversion specifier.
        // Assuming leading zeros eliminated, thus the size of 32 for
        // integral types.
        char __xtrc[32];
--- 547,552 ----
*************** namespace std
*** 600,615 ****
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
  			     numeric_limits<unsigned long long>::digits10 + 1,
  			     __base);
! 
!       // Stage 2: convert and store results.
!       char* __sanity;
!       errno = 0;
!       unsigned long long __ull = strtoull(__xtrc, &__sanity, __base);
!       if (!(__err & ios_base::failbit)
!           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
!         __v = __ull;
!       else
!         __err |= ios_base::failbit;
        return __beg;
      }
  #endif
--- 554,560 ----
        __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
  			     numeric_limits<unsigned long long>::digits10 + 1,
  			     __base);
!       __convert_to_v(__xtrc, __v, __err, _S_c_locale, __base);
        return __beg;
      }
  #endif
*************** namespace std
*** 620,643 ****
      do_get(iter_type __beg, iter_type __end, ios_base& __io, 
  	   ios_base::iostate& __err, float& __v) const
      {
-       // Stage 1: extract and determine the conversion specifier.
        string __xtrc;
        __xtrc.reserve(32);
        __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
! 
!       // Stage 2: convert and store results.
!       char* __sanity;
!       errno = 0;
! #ifdef _GLIBCPP_USE_C99
!       float __f = strtof(__xtrc.c_str(), &__sanity);
! #else
!       float __f = static_cast<float>(strtod(__xtrc.c_str(), &__sanity));
! #endif
!       if (!(__err & ios_base::failbit)
!           && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
!         __v = __f;
!       else
!         __err |= ios_base::failbit;
        return __beg;
      }
  
--- 565,574 ----
      do_get(iter_type __beg, iter_type __end, ios_base& __io, 
  	   ios_base::iostate& __err, float& __v) const
      {
        string __xtrc;
        __xtrc.reserve(32);
        __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
!       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
        return __beg;
      }
  
*************** namespace std
*** 647,666 ****
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, double& __v) const
      {
-       // Stage 1: extract and determine the conversion specifier.
        string __xtrc;
        __xtrc.reserve(32);
        __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
! 
!       // Stage 2: convert and store results.
!       char* __sanity;
!       errno = 0;
!       double __d = strtod(__xtrc.c_str(), &__sanity);
!       if (!(__err & ios_base::failbit)
!           && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
!         __v = __d;
!       else
!         __err |= ios_base::failbit;
        return __beg;
      }
  
--- 578,587 ----
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, double& __v) const
      {
        string __xtrc;
        __xtrc.reserve(32);
        __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
!       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
        return __beg;
      }
  
*************** namespace std
*** 670,711 ****
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, long double& __v) const
      {
-       // Stage 1: extract and determine the conversion specifier.
        string __xtrc;
        __xtrc.reserve(32);
        __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
! 
! #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
!       // Stage 2: convert and store results.
!       char* __sanity;
!       errno = 0;
!       long double __ld = strtold(__xtrc.c_str(), &__sanity);
!       if (!(__err & ios_base::failbit)
!           && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
!         __v = __ld;
! #else
!       // Stage 2: determine a conversion specifier.
!       ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
!       const char* __conv;
!       if (__basefield == ios_base::oct)
!         __conv = "%Lo";
!       else if (__basefield == ios_base::hex)
!         __conv = "%LX";
!       else if (__basefield == 0)
!         __conv = "%Li";
!       else
!         __conv = "%Lf";
! 
!       // Stage 3: store results.
!       typedef typename char_traits<_CharT>::int_type int_type;
!       long double __ld;
!       int __p = sscanf(__xtrc.c_str(), __conv, &__ld);
!       if (!(__err & ios_base::failbit) && __p 
! 	  && static_cast<int_type>(__p) != char_traits<_CharT>::eof())
!         __v = __ld;
! #endif
!       else
!         __err |= ios_base::failbit;
        return __beg;
      }
  
--- 591,600 ----
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, long double& __v) const
      {
        string __xtrc;
        __xtrc.reserve(32);
        __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
!       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
        return __beg;
      }
  
*************** namespace std
*** 722,728 ****
                               | ios_base::uppercase | ios_base::internal);
        __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
  
-       // Stage 1: extract and determine the conversion specifier.
        // Assuming leading zeros eliminated, thus the size of 32 for
        // integral types.
        char __xtrc[32];
--- 611,616 ----
*************** namespace std
*** 731,748 ****
  			     numeric_limits<unsigned long>::digits10 + 1,
  			     __base);
  
-       // Stage 2: convert and store results.
-       char* __sanity;
-       errno = 0;
-       void* __vp = reinterpret_cast<void*>(strtoul(__xtrc, &__sanity, __base));
-       if (!(__err & ios_base::failbit)
-           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
-         __v = __vp;
-       else
-         __err |= ios_base::failbit;
- 
        // Reset from hex formatted input
        __io.flags(__fmt);
        return __beg;
      }
  
--- 619,633 ----
  			     numeric_limits<unsigned long>::digits10 + 1,
  			     __base);
  
        // Reset from hex formatted input
        __io.flags(__fmt);
+ 
+       unsigned long __ul;
+       __convert_to_v(__xtrc, __ul, __err, _S_c_locale, __base);
+       if (!(__err & ios_base::failbit))
+ 	__v = reinterpret_cast<void*>(__ul);
+       else 
+ 	__err |= ios_base::failbit;
        return __beg;
      }
  
*************** namespace std
*** 787,795 ****
  	int __len;
  	// [22.2.2.2.2] Stage 1, numeric conversion to character.
  	if (_S_format_float(__io, __fbuf, __mod, __prec))
! 	  __len = sprintf(__cs, __fbuf, __prec, __v);
  	else
! 	  __len = sprintf(__cs, __fbuf, __v);
  	return _M_widen_float(__s, __io, __fill, __cs, __len);
        }
  
--- 672,680 ----
  	int __len;
  	// [22.2.2.2.2] Stage 1, numeric conversion to character.
  	if (_S_format_float(__io, __fbuf, __mod, __prec))
! 	  __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale, __prec);
  	else
! 	  __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale);
  	return _M_widen_float(__s, __io, __fill, __cs, __len);
        }
  
*************** namespace std
*** 807,813 ****
  	// Long enough for the max format spec.
  	char __fbuf[16];
  	_S_format_int(__io, __fbuf, __mod, __modl);
! 	int __len = sprintf(__cs, __fbuf, __v);
  	return _M_widen_int(__s, __io, __fill, __cs, __len);
        }
  
--- 692,698 ----
  	// Long enough for the max format spec.
  	char __fbuf[16];
  	_S_format_int(__io, __fbuf, __mod, __modl);
! 	int __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale);
  	return _M_widen_int(__s, __io, __fill, __cs, __len);
        }
  
*************** namespace std
*** 1043,1064 ****
        const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
        const _CharT* __wcs = __str.c_str();
        __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);      
! 
! #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
!       char* __sanity;
!       errno = 0;
!       long double __ld = strtold(__cs, &__sanity);
!       if (!(__err & ios_base::failbit)
!           && __sanity != __cs && *__sanity == '\0' && errno == 0)
!         __units = __ld;
! #else
!       typedef typename char_traits<_CharT>::int_type int_type;
!       long double __ld;
!       int __p = sscanf(__cs, "%Lf", &__ld);
!       if (!(__err & ios_base::failbit)
! 	  && __p && static_cast<int_type>(__p) != char_traits<_CharT>::eof())
!         __units = __ld;
! #endif
        return __beg;
      }
  
--- 928,934 ----
        const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
        const _CharT* __wcs = __str.c_str();
        __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);      
!       __convert_to_v(__cs, __units, __err, _S_c_locale);
        return __beg;
      }
  
*************** namespace std
*** 1253,1259 ****
        const int __n = numeric_limits<long double>::digits10;
        char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
        _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
!       int __len = sprintf(__cs, "%.01Lf", __units);
        __ctype.widen(__cs, __cs + __len, __ws);
        string_type __digits(__ws);
        return this->do_put(__s, __intl, __io, __fill, __digits); 
--- 1123,1129 ----
        const int __n = numeric_limits<long double>::digits10;
        char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
        _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
!       int __len = __convert_from_v(__cs, "%.01Lf", __units, _S_c_locale);
        __ctype.widen(__cs, __cs + __len, __ws);
        string_type __digits(__ws);
        return this->do_put(__s, __intl, __io, __fill, __digits); 
*************** namespace std
*** 1867,1875 ****
  	}
        if (__i == 2 || __i == 4)
  	{
! 	  int __year = atoi(__digits.c_str());
! 	  __year = __i == 2 ? __year : __year - 1900; 
! 	  __tm->tm_year = __year;
  	}
        else
  	__err |= ios_base::failbit;
--- 1737,1749 ----
  	}
        if (__i == 2 || __i == 4)
  	{
! 	  long __l;
! 	  __convert_to_v(__digits.c_str(), __l, __err, _S_c_locale);
! 	  if (!(__err & ios_base::failbit) && __l <= INT_MAX)
! 	    {
! 	      __l = __i == 2 ? __l : __l - 1900; 
! 	      __tm->tm_year = static_cast<int>(__l);
! 	    }
  	}
        else
  	__err |= ios_base::failbit;
*************** namespace std
*** 2013,2018 ****
--- 1887,1916 ----
  	__val = *__lo + ((__val << 7) | 
  		       (__val >> (numeric_limits<unsigned long>::digits - 1)));
        return static_cast<long>(__val);
+     }
+ 
+   // Convert string to numeric value of type T and store results.  
+   // NB: This is specialized for all required types, there is no
+   // generic definition.
+   template <typename _T>
+     void
+     __convert_to_v(const char* __in, _T& __out, ios_base::iostate& __err, 
+ 		   const __c_locale& __cloc, int __base = 10);
+ 
+   // Convert numeric value of type T to string and return length of string.
+   template <typename _T>
+     int
+     __convert_from_v(char* __out, const char* __fmt, _T __v, 
+ 		     const __c_locale&, int __prec = -1)
+     {
+       int __ret;
+       const char* __old = setlocale(LC_ALL, "C");
+       if (__prec >= 0)
+ 	__ret = sprintf(__out, __fmt, __prec, __v);
+       else
+ 	__ret = sprintf(__out, __fmt, __v);
+       setlocale(LC_ALL, __old);
+       return __ret;
      }
  
    // Construct correctly padded string, as per 22.2.2.2.2
Index: include/bits/localefwd.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/localefwd.h,v
retrieving revision 1.23
diff -c -p -r1.23 localefwd.h
*** localefwd.h	2002/01/04 21:27:31	1.23
--- localefwd.h	2002/01/22 20:43:19
***************
*** 1,6 ****
  // Locale support -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001 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
--- 1,7 ----
  // Locale support -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
! // 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
***************
*** 43,51 ****
  
  #include <bits/c++config.h>
  #include <bits/c++locale.h>     // Defines __c_locale, config-specific includes
! #include <climits>	// For CHAR_BIT
! #include <cctype>	// For isspace, etc.
! #include <string> 	// For string
  #include <bits/functexcept.h>
  
  namespace std
--- 44,52 ----
  
  #include <bits/c++config.h>
  #include <bits/c++locale.h>     // Defines __c_locale, config-specific includes
! #include <climits>		// For CHAR_BIT
! #include <cctype>		// For isspace, etc.
! #include <string> 		// For string
  #include <bits/functexcept.h>
  
  namespace std
*************** namespace std
*** 295,301 ****
    };
  
  
!   // locale implementation object
    class locale::_Impl
    {
    public:
--- 296,302 ----
    };
  
  
!   // Implementation object for locale 
    class locale::_Impl
    {
    public:
*************** namespace std
*** 390,400 ****
      friend class locale::_Impl;
      friend class __enc_traits;
  
    protected:
      // Contains data from the underlying "C" library for default "C"
!     // and "POSIX" locales.
      static __c_locale		     _S_c_locale;
! 
      explicit 
      facet(size_t __refs = 0) throw();
  
--- 391,404 ----
      friend class locale::_Impl;
      friend class __enc_traits;
  
+   private:
+     size_t _M_references;
+ 
    protected:
      // Contains data from the underlying "C" library for default "C"
!     // or "POSIX" locale.
      static __c_locale		     _S_c_locale;
!     
      explicit 
      facet(size_t __refs = 0) throw();
  
*************** namespace std
*** 411,428 ****
      _S_destroy_c_locale(__c_locale& __cloc);
  
    private:
-     size_t _M_references;
- 
      void 
      _M_add_reference() throw();
  
      void 
      _M_remove_reference() throw();
  
!     facet(const facet&);  // not defined
  
      void 
!     operator=(const facet&);  // not defined
    };
  
  
--- 415,430 ----
      _S_destroy_c_locale(__c_locale& __cloc);
  
    private:
      void 
      _M_add_reference() throw();
  
      void 
      _M_remove_reference() throw();
  
!     facet(const facet&);  // Not defined.
  
      void 
!     operator=(const facet&);  // Not defined.
    };
  
  
Index: src/locale-inst.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/locale-inst.cc,v
retrieving revision 1.26
diff -c -p -r1.26 locale-inst.cc
*** locale-inst.cc	2002/01/04 21:27:35	1.26
--- locale-inst.cc	2002/01/22 20:43:21
*************** namespace std
*** 372,377 ****
--- 372,403 ----
  					  streamsize, const bool);
  #endif // _GLIBCPP_USE_WCHAR_T
  
+   template
+     int
+     __convert_from_v(char*, const char*, double, const __c_locale&, int);
+ 
+   template
+     int
+     __convert_from_v(char*, const char*, long double, const __c_locale&, int);
+ 
+   template
+     int
+     __convert_from_v(char*, const char*, long, const __c_locale&, int);
+ 
+   template
+     int
+     __convert_from_v(char*, const char*, unsigned long, 
+ 		     const __c_locale&, int);
+ 
+   template
+     int
+     __convert_from_v(char*, const char*, long long, const __c_locale&, int);
+ 
+   template
+     int
+     __convert_from_v(char*, const char*, unsigned long long, 
+ 		     const __c_locale&, int);
+ 
    template 
      locale::facet** 
      fill_n<locale::facet**, size_t, locale::facet*>
*************** namespace std
*** 388,390 ****
--- 414,429 ----
           __normal_iterator<locale::facet**, vector<locale::facet*> >,
           locale::facet* const&);
  } // namespace std
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
Index: testsuite/22_locale/codecvt_members_char_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/codecvt_members_char_char.cc,v
retrieving revision 1.1
diff -c -p -r1.1 codecvt_members_char_char.cc
*** codecvt_members_char_char.cc	2001/08/28 06:19:35	1.1
--- codecvt_members_char_char.cc	2002/01/22 20:43:22
***************
*** 1,6 ****
  // 2000-08-17 Benjamin Kosnik <bkoz@cygnus.com>
  
! // Copyright (C) 2000 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
--- 1,6 ----
  // 2000-08-17 Benjamin Kosnik <bkoz@cygnus.com>
  
! // Copyright (C) 2000, 2002 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
*************** void test01()
*** 79,87 ****
    delete [] c_arr;
  }
  
  int main ()
  {
    test01();
! 
    return 0;
  }
--- 79,103 ----
    delete [] c_arr;
  }
  
+ // libstdc++/5280
+ void test02()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main ()
  {
    test01();
!   test02();
    return 0;
  }
Index: testsuite/22_locale/codecvt_members_wchar_t_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/codecvt_members_wchar_t_char.cc,v
retrieving revision 1.1
diff -c -p -r1.1 codecvt_members_wchar_t_char.cc
*** codecvt_members_wchar_t_char.cc	2001/08/28 06:19:35	1.1
--- codecvt_members_wchar_t_char.cc	2002/01/22 20:43:22
***************
*** 1,6 ****
  // 2000-08-18 Benjamin Kosnik <bkoz@cygnus.com>
  
! // Copyright (C) 2000 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
--- 1,6 ----
  // 2000-08-18 Benjamin Kosnik <bkoz@cygnus.com>
  
! // Copyright (C) 2000, 2002 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
*************** void test01()
*** 110,115 ****
--- 110,131 ----
    delete [] e_arr;
    delete [] i_arr;
  }
+ 
+ // libstdc++/5280
+ void test02()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif /* !defined(_GLIBCPP_USE_WCHAR_T) */
  
  
*************** int main ()
*** 117,122 ****
--- 133,139 ----
  {
  #if _GLIBCPP_USE_WCHAR_T
    test01();
+   test02();
  #endif 
  
    return 0;
Index: testsuite/22_locale/collate_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/collate_members_char.cc,v
retrieving revision 1.1
diff -c -p -r1.1 collate_members_char.cc
*** collate_members_char.cc	2001/08/28 06:19:35	1.1
--- collate_members_char.cc	2002/01/22 20:43:23
***************
*** 1,6 ****
  // 2001-08-15 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // 2001-08-15 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001, 2002 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
*************** void test01()
*** 129,138 ****
    VERIFY(i1 == i2);
  }
  
  int main()
  {
    test01();
! 
    return 0;
  }
  
--- 129,154 ----
    VERIFY(i1 == i2);
  }
  
+ // libstdc++/5280
+ void test02()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main()
  {
    test01();
!   test02();
    return 0;
  }
  
Index: testsuite/22_locale/collate_members_wchar_t.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/collate_members_wchar_t.cc,v
retrieving revision 1.1
diff -c -p -r1.1 collate_members_wchar_t.cc
*** collate_members_wchar_t.cc	2001/08/28 06:19:35	1.1
--- collate_members_wchar_t.cc	2002/01/22 20:43:23
***************
*** 1,6 ****
  // 2001-08-17 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // 2001-08-17 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001, 2002 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
*************** void test01()
*** 128,139 ****
--- 128,156 ----
    i2 = coll_de.compare(strlit3, strlit3 + size3, strlit4, strlit4 + size4);
    VERIFY(i1 == i2);
  }
+ 
+ // libstdc++/5280
+ void test02()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif
  
  int main()
  {
  #if _GLIBCPP_USE_WCHAR_T
    test01();
+   test02();
  #endif
    return 0;
  }
Index: testsuite/22_locale/ctype_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/ctype_members_char.cc,v
retrieving revision 1.4
diff -c -p -r1.4 ctype_members_char.cc
*** ctype_members_char.cc	2002/01/17 03:59:41	1.4
--- ctype_members_char.cc	2002/01/22 20:43:23
*************** public:
*** 243,252 ****
    { classic_table(); }
  };
  
  int main() 
  {
    test01();
    test02();
! 
    return 0;
  }
--- 243,269 ----
    { classic_table(); }
  };
  
+ // libstdc++/5280
+ void test03()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main() 
  {
    test01();
    test02();
!   test03();
    return 0;
  }
Index: testsuite/22_locale/ctype_members_wchar_t.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/ctype_members_wchar_t.cc,v
retrieving revision 1.2
diff -c -p -r1.2 ctype_members_wchar_t.cc
*** ctype_members_wchar_t.cc	2001/12/15 07:05:04	1.2
--- ctype_members_wchar_t.cc	2002/01/22 20:43:24
***************
*** 1,6 ****
  // 2000-09-01 Benjamin Kosnik <bkoz@redhat.com>
  
! // Copyright (C) 2000, 2001 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
--- 1,6 ----
  // 2000-09-01 Benjamin Kosnik <bkoz@redhat.com>
  
! // Copyright (C) 2000, 2001, 2002 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
*************** void test01()
*** 96,107 ****
--- 96,124 ----
    assert(test);
  #endif
  }
+ 
+ // libstdc++/5280
+ void test03()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif /* !defined(_GLIBCPP_USE_WCHAR_T) */
  
  int main() 
  {
  #if _GLIBCPP_USE_WCHAR_T
    test01();
+   test03();
  #endif 
  
    return 0;
Index: testsuite/22_locale/messages_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/messages_members_char.cc,v
retrieving revision 1.1
diff -c -p -r1.1 messages_members_char.cc
*** messages_members_char.cc	2001/08/28 06:19:35	1.1
--- messages_members_char.cc	2002/01/22 20:43:24
***************
*** 1,6 ****
  // 2001-07-17 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // 2001-07-17 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001, 2002 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
*************** void test01()
*** 79,90 ****
    VERIFY ( s01 == "please" );
    VERIFY ( s02 == "thank you" );
    mssg_us.close(cat_us);
  
!  }
  
  int main()
  {
    test01();
! 
    return 0;
  }
--- 79,105 ----
    VERIFY ( s01 == "please" );
    VERIFY ( s02 == "thank you" );
    mssg_us.close(cat_us);
+ }
  
! // libstdc++/5280
! void test02()
! {
!   // Set the global locale to non-"C".
!   std::locale loc_de("de_DE");
!   std::locale::global(loc_de);
! 
!   // Set LANG environment variable to de_DE.
!   const char* oldLANG = getenv("LANG");
!   if (!setenv("LANG", "de_DE", 1))
!     {
!       test01();
!       setenv("LANG", oldLANG, 1);
!     }
! }
  
  int main()
  {
    test01();
!   test02();
    return 0;
  }
Index: testsuite/22_locale/money_get_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/money_get_members_char.cc,v
retrieving revision 1.6
diff -c -p -r1.6 money_get_members_char.cc
*** money_get_members_char.cc	2002/01/16 19:57:36	1.6
--- money_get_members_char.cc	2002/01/22 20:43:25
*************** void test03()
*** 289,298 ****
--- 289,317 ----
    VERIFY( rem2 == "Eleanor Roosevelt" );
  }
  
+ // libstdc++/5280
+ void test04()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       test03();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main()
  {
    test01();
    test02();
    test03();
+   test04();
    return 0;
  }
Index: testsuite/22_locale/money_get_members_wchar_t.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/money_get_members_wchar_t.cc,v
retrieving revision 1.5
diff -c -p -r1.5 money_get_members_wchar_t.cc
*** money_get_members_wchar_t.cc	2002/01/16 19:57:37	1.5
--- money_get_members_wchar_t.cc	2002/01/22 20:43:26
*************** void test03()
*** 290,295 ****
--- 290,313 ----
    VERIFY( res2 == 1 );
    VERIFY( rem2 == L"Eleanor Roosevelt" );
  }
+ 
+ // libstdc++/5280
+ void test04()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       test03();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif
  
  
*************** int main()
*** 299,304 ****
--- 317,323 ----
    test01();
    test02();
    test03();
+   test04();
  #endif
    return 0;
  }
Index: testsuite/22_locale/money_put_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/money_put_members_char.cc,v
retrieving revision 1.7
diff -c -p -r1.7 money_put_members_char.cc
*** money_put_members_char.cc	2002/01/16 19:57:37	1.7
--- money_put_members_char.cc	2002/01/22 20:43:26
*************** void test03()
*** 283,292 ****
--- 283,311 ----
    VERIFY( sanity2 == "1943" );
  }
  
+ // libstdc++/5280
+ void test04()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       test03();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main()
  {
    test01();
    test02();
    test03();
+   test04();
    return 0;
  }
Index: testsuite/22_locale/money_put_members_wchar_t.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc,v
retrieving revision 1.6
diff -c -p -r1.6 money_put_members_wchar_t.cc
*** money_put_members_wchar_t.cc	2002/01/16 19:57:37	1.6
--- money_put_members_wchar_t.cc	2002/01/22 20:43:27
*************** void test03()
*** 282,287 ****
--- 282,305 ----
    VERIFY( res == L"1943xxxxxxxxxxxxx" );
    VERIFY( sanity2 == L"1943" );
  }
+ 
+ // libstdc++/5280
+ void test04()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       test03();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif
  
  int main()
*************** int main()
*** 290,295 ****
--- 308,314 ----
    test01();
    test02();
    test03();
+   test04();
  #endif
    return 0;
  }
Index: testsuite/22_locale/moneypunct_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/moneypunct_members_char.cc,v
retrieving revision 1.3
diff -c -p -r1.3 moneypunct_members_char.cc
*** moneypunct_members_char.cc	2001/09/20 09:07:37	1.3
--- moneypunct_members_char.cc	2002/01/22 20:43:27
***************
*** 1,6 ****
  // 2001-08-23 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // 2001-08-23 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001, 2002 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
*************** void test01()
*** 105,113 ****
    VERIFY(static_cast<part>(neg1.field[3]) != static_cast<part>(neg2.field[3]));
  }
  
  int main()
  {
    test01();
! 
    return 0;
  }
--- 105,129 ----
    VERIFY(static_cast<part>(neg1.field[3]) != static_cast<part>(neg2.field[3]));
  }
  
+ // libstdc++/5280
+ void test02()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main()
  {
    test01();
!   test02();
    return 0;
  }
Index: testsuite/22_locale/moneypunct_members_wchar_t.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/moneypunct_members_wchar_t.cc,v
retrieving revision 1.2
diff -c -p -r1.2 moneypunct_members_wchar_t.cc
*** moneypunct_members_wchar_t.cc	2001/09/20 09:07:37	1.2
--- moneypunct_members_wchar_t.cc	2002/01/22 20:43:28
***************
*** 1,6 ****
  // 2001-09-09 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // 2001-09-09 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001, 2002 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
*************** void test01()
*** 105,116 ****
--- 105,133 ----
    VERIFY(static_cast<part>(neg1.field[2]) != static_cast<part>(neg2.field[2]));
    VERIFY(static_cast<part>(neg1.field[3]) != static_cast<part>(neg2.field[3]));
  }
+ 
+ // libstdc++/5280
+ void test02()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif
  
  int main()
  {
  #ifdef _GLIBCPP_USE_WCHAR_T
    test01();
+   test02();
  #endif
    return 0;
  }
Index: testsuite/22_locale/num_get_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/num_get_members_char.cc,v
retrieving revision 1.4
diff -c -p -r1.4 num_get_members_char.cc
*** num_get_members_char.cc	2002/01/16 00:51:45	1.4
--- num_get_members_char.cc	2002/01/22 20:43:28
*************** void test02()
*** 313,322 ****
--- 313,340 ----
    VERIFY( rem5 == " Durack" );
  }
  
+ // libstdc++/5280
+ void test03()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main()
  {
    test01();
    test02();
+   test03();
    return 0;
  }
  
Index: testsuite/22_locale/num_get_members_wchar_t.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/num_get_members_wchar_t.cc,v
retrieving revision 1.2
diff -c -p -r1.2 num_get_members_wchar_t.cc
*** num_get_members_wchar_t.cc	2002/01/16 00:51:45	1.2
--- num_get_members_wchar_t.cc	2002/01/22 20:43:29
*************** void test02()
*** 314,319 ****
--- 314,336 ----
    VERIFY( b == true );
    VERIFY( rem5 == L" Durack" );
  }
+ 
+ // libstdc++/5280
+ void test03()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif
  
  int main()
*************** int main()
*** 321,326 ****
--- 338,344 ----
  #ifdef _GLIBCPP_USE_WCHAR_T
    test01();
    test02();
+   test03();
  #endif
    return 0;
  }
Index: testsuite/22_locale/num_put_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/num_put_members_char.cc,v
retrieving revision 1.3
diff -c -p -r1.3 num_put_members_char.cc
*** num_put_members_char.cc	2002/01/16 06:06:58	1.3
--- num_put_members_char.cc	2002/01/22 20:43:30
*************** void test02()
*** 291,299 ****
--- 291,319 ----
    VERIFY( sanity5[1] == 'x' );
  }
  
+ // libstdc++/5280
+ void test03()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main()
  {
    test01();
    test02();
+   test03();
    return 0;
  }
+ 
+ 
Index: testsuite/22_locale/num_put_members_wchar_t.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/num_put_members_wchar_t.cc,v
retrieving revision 1.3
diff -c -p -r1.3 num_put_members_wchar_t.cc
*** num_put_members_wchar_t.cc	2002/01/16 06:06:59	1.3
--- num_put_members_wchar_t.cc	2002/01/22 20:43:30
*************** void test02()
*** 290,295 ****
--- 290,312 ----
    VERIFY( sanity5.size() );
    VERIFY( sanity5[1] == L'x' );
  }
+ 
+ // libstdc++/5280
+ void test03()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif
  
  int main()
*************** int main()
*** 297,302 ****
--- 314,320 ----
  #ifdef _GLIBCPP_USE_WCHAR_T
    test01();
    test02();
+   test03();
  #endif
    return 0;
  }
*************** int main()
*** 304,306 ****
--- 322,325 ----
  
  // Diana D. Brooks, former chief executive of Sotheby's
  // art-thief extraordinaire
+ 
Index: testsuite/22_locale/numpunct_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/numpunct_members_char.cc,v
retrieving revision 1.3
diff -c -p -r1.3 numpunct_members_char.cc
*** numpunct_members_char.cc	2001/11/28 04:07:10	1.3
--- numpunct_members_char.cc	2002/01/22 20:43:31
***************
*** 1,6 ****
  // 2001-01-17 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // 2001-01-17 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001, 2002 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
*************** void test01()
*** 83,91 ****
    // VERIFY( f2 != f3 );
  }
  
  int main()
  {
    test01();
! 
    return 0;
  }
--- 83,107 ----
    // VERIFY( f2 != f3 );
  }
  
+ // libstdc++/5280
+ void test02()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main()
  {
    test01();
!   test02();
    return 0;
  }
Index: testsuite/22_locale/numpunct_members_wchar_t.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/numpunct_members_wchar_t.cc,v
retrieving revision 1.2
diff -c -p -r1.2 numpunct_members_wchar_t.cc
*** numpunct_members_wchar_t.cc	2001/12/04 20:13:40	1.2
--- numpunct_members_wchar_t.cc	2002/01/22 20:43:31
***************
*** 1,6 ****
  // 2001-11-20 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001 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
--- 1,6 ----
  // 2001-11-20 Benjamin Kosnik  <bkoz@redhat.com>
  
! // Copyright (C) 2001, 2002 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
*************** void test01()
*** 80,91 ****
--- 80,108 ----
    VERIFY( dp2 != dp4 );
    VERIFY( th2 != th4 );
  }
+ 
+ // libstdc++/5280
+ void test02()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif
  
  int main()
  {
  #ifdef _GLIBCPP_USE_WCHAR_T
    test01();
+   test02();
  #endif
    return 0;
  }
Index: testsuite/22_locale/time_get_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/time_get_members_char.cc,v
retrieving revision 1.4
diff -c -p -r1.4 time_get_members_char.cc
*** time_get_members_char.cc	2002/01/16 19:57:37	1.4
--- time_get_members_char.cc	2002/01/22 20:43:33
*************** void test02()
*** 193,198 ****
--- 193,199 ----
    //             ios_base::iostate&, tm*) const
  
    // sanity checks for "C" locale
+   iss.imbue(loc_c);
    iss.str("Sunday");
    iterator_type is_it01(iss);
    tm time01;
*************** void test03()
*** 315,320 ****
--- 316,322 ----
    //               ios_base::iostate&, tm*) const
  
    // sanity checks for "C" locale
+   iss.imbue(loc_c);
    iss.str("April");
    iterator_type is_it01(iss);
    tm time01;
*************** void test04()
*** 436,441 ****
--- 438,444 ----
    // get_year(iter_type, iter_type, ios_base&, ios_base::iostate&, tm*) const
  
    // sanity checks for "C" locale
+   iss.imbue(loc_c);
    iss.str("1971");
    iterator_type is_it01(iss);
    tm time01;
*************** void test05()
*** 527,532 ****
--- 530,536 ----
    // get_date(iter_type, iter_type, ios_base&, ios_base::iostate&, tm*) const
  
    // sanity checks for "C" locale
+   iss.imbue(loc_c);
    iss.str("04/04/71");
    iterator_type is_it01(iss);
    tm time01;
*************** void test06()
*** 672,677 ****
--- 676,702 ----
    VERIFY( rem5 ==  " Cindy Sherman" );
  }
  
+ // libstdc++/5280
+ void test07()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       test03();
+       test04();
+       test05();
+       test06();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main()
  {
    test01();
*************** int main()
*** 681,685 ****
--- 706,712 ----
    test05();
    
    test06();
+   
+   test07();
    return 0;
  }
Index: testsuite/22_locale/time_get_members_wchar_t.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/time_get_members_wchar_t.cc,v
retrieving revision 1.3
diff -c -p -r1.3 time_get_members_wchar_t.cc
*** time_get_members_wchar_t.cc	2002/01/16 19:57:37	1.3
--- time_get_members_wchar_t.cc	2002/01/22 20:43:34
*************** void test02()
*** 193,198 ****
--- 193,199 ----
    //             ios_base::iostate&, tm*) const
  
    // sanity checks for "C" locale
+   iss.imbue(loc_c);
    iss.str(L"Sunday");
    iterator_type is_it01(iss);
    tm time01;
*************** void test03()
*** 315,320 ****
--- 316,322 ----
    //               ios_base::iostate&, tm*) const
  
    // sanity checks for "C" locale
+   iss.imbue(loc_c);
    iss.str(L"April");
    iterator_type is_it01(iss);
    tm time01;
*************** void test04()
*** 436,441 ****
--- 438,444 ----
    // get_year(iter_type, iter_type, ios_base&, ios_base::iostate&, tm*) const
  
    // sanity checks for "C" locale
+   iss.imbue(loc_c);
    iss.str(L"1971");
    iterator_type is_it01(iss);
    tm time01;
*************** void test05()
*** 527,532 ****
--- 530,536 ----
    // get_date(iter_type, iter_type, ios_base&, ios_base::iostate&, tm*) const
  
    // sanity checks for "C" locale
+   iss.imbue(loc_c);
    iss.str(L"04/04/71");
    iterator_type is_it01(iss);
    tm time01;
*************** void test06()
*** 671,676 ****
--- 675,701 ----
    VERIFY( tm1.tm_year == time_sanity.tm_year );
    VERIFY( rem5 ==  L" Cindy Sherman" );
  }
+ 
+ // libstdc++/5280
+ void test07()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       test03();
+       test04();
+       test05();
+       test06();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif
  
  int main()
*************** int main()
*** 683,688 ****
--- 708,715 ----
    test05();
  
    test06();
+ 
+   test07();
  #endif
    return 0;
  }
Index: testsuite/22_locale/time_put_members_char.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/time_put_members_char.cc,v
retrieving revision 1.4
diff -c -p -r1.4 time_put_members_char.cc
*** time_put_members_char.cc	2002/01/16 19:57:37	1.4
--- time_put_members_char.cc	2002/01/22 20:43:35
*************** void test02()
*** 231,239 ****
--- 231,257 ----
    VERIFY( sanity2 == "Tuesday" );
  }
  
+ // libstdc++/5280
+ void test03()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
+ 
  int main()
  {
    test01();
    test02();
+   test03();
    return 0;
  }
Index: testsuite/22_locale/time_put_members_wchar_t.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/22_locale/time_put_members_wchar_t.cc,v
retrieving revision 1.3
diff -c -p -r1.3 time_put_members_wchar_t.cc
*** time_put_members_wchar_t.cc	2002/01/16 19:57:37	1.3
--- time_put_members_wchar_t.cc	2002/01/22 20:43:36
*************** void test02()
*** 232,237 ****
--- 232,254 ----
    VERIFY( res == L"Tuesdayxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" );
    VERIFY( sanity2 == L"Tuesday" );
  }
+ 
+ // libstdc++/5280
+ void test03()
+ {
+   // Set the global locale to non-"C".
+   std::locale loc_de("de_DE");
+   std::locale::global(loc_de);
+ 
+   // Set LANG environment variable to de_DE.
+   const char* oldLANG = getenv("LANG");
+   if (!setenv("LANG", "de_DE", 1))
+     {
+       test01();
+       test02();
+       setenv("LANG", oldLANG, 1);
+     }
+ }
  #endif
  
  int main()
*************** int main()
*** 239,244 ****
--- 256,262 ----
  #ifdef _GLIBCPP_USE_WCHAR_T
    test01();
    test02();
+   test03();
  #endif
    return 0;
  }


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