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]

[PATCH] Fix libstdc++/9581 and libstdc++/9870


Hi,

This fixes libstdc++/9581 and the second half of libstdc++/9870.
I believe the first half of libstdc++/9870 is not a bug; using
mbsrtowcs wouldn't allow do_widen to handle stateful encodings
(because there is no way to pass the state to the function),
nor would it allow do_widen to handle multibyte characters
(do_widen only accepts a single byte as a parameter).

The documentation for do_narrow and do_widen could still use
some improvement.

Tested on linux on x86.

Petur


2003-03-13  Petur Runolfsson  <peturr02 at ru dot is>

	PR libstdc++/9581
	PR libstdc++/9870
	* config/locale/generic/ctype_members.cc,
	* config/locale/gnu/ctype_members.cc
	(ctype<wchar_t>::do_widen(char)):  Cast argument to
	unsigned char before passing to btowc.
	(ctype<wchar_t>::do_widen(const char*, const char*, wchar_t*)):
	Convert characters with btowc instead of mbsrtowcs.
	(ctype<wchar_t>::do_narrow(const wchar_t*, const wchar_t*,
	char, char*):
	Convert characters with wctob instead of wcsrtombs.

	* testsuite/22_locale/ctype/narrow/wchar_t/3.cc:  New test.
	* testsuite/22_locale/ctype/widen/wchar_t/2.cc:  New test.	
	* testsuite/22_locale/ctype/widen/wchar_t/3.cc:  New test.	
	
Index: libstdc++-v3/config/locale/generic/ctype_members.cc
===================================================================
RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/config/locale/generic/ctype_members.cc,v
retrieving revision 1.1.1.1
diff -c -3 -p -r1.1.1.1 ctype_members.cc
*** libstdc++-v3/config/locale/generic/ctype_members.cc	15 Feb 2003 18:16:14 -0000	1.1.1.1
--- libstdc++-v3/config/locale/generic/ctype_members.cc	13 Mar 2003 00:17:15 -0000
*************** namespace std
*** 158,172 ****
    wchar_t
    ctype<wchar_t>::
    do_widen(char __c) const
!   { return btowc(__c); }
    
    const char* 
    ctype<wchar_t>::
    do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
    {
!     mbstate_t __state;
!     memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t));
!     mbsrtowcs(__dest, &__lo, __hi - __lo, &__state);
      return __hi;
    }
  
--- 158,175 ----
    wchar_t
    ctype<wchar_t>::
    do_widen(char __c) const
!   { return btowc(static_cast<unsigned char>(__c)); }
    
    const char* 
    ctype<wchar_t>::
    do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
    {
!     while (__lo < __hi)
!       {
! 	*__dest = btowc(static_cast<unsigned char>(*__lo));
! 	++__lo;
! 	++__dest;
!       }
      return __hi;
    }
  
*************** namespace std
*** 183,204 ****
    do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault, 
  	    char* __dest) const
    {
!     size_t __offset = 0;
!     while (true)
        {
! 	const wchar_t* __start = __lo + __offset;        
! 	size_t __len = __hi - __start;
! 	
! 	mbstate_t __state;
! 	memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t));
! 	size_t __con = wcsrtombs(__dest + __offset, &__start, __len, &__state);
! 	if (__con != __len && __start != 0)
! 	  {
! 	    __offset = __start - __lo;          
! 	    __dest[__offset++] = __dfault;
! 	  }
! 	else
! 	  break;
        }
      return __hi;
    }
--- 186,197 ----
    do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault, 
  	    char* __dest) const
    {
!     while (__lo < __hi)
        {
! 	int __c = wctob(*__lo);
! 	*__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
! 	++__lo;
! 	++__dest;
        }
      return __hi;
    }
Index: libstdc++-v3/config/locale/gnu/ctype_members.cc
===================================================================
RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/config/locale/gnu/ctype_members.cc,v
retrieving revision 1.1.1.1
diff -c -3 -p -r1.1.1.1 ctype_members.cc
*** libstdc++-v3/config/locale/gnu/ctype_members.cc	15 Feb 2003 18:16:14 -0000	1.1.1.1
--- libstdc++-v3/config/locale/gnu/ctype_members.cc	13 Mar 2003 00:15:39 -0000
*************** namespace std
*** 169,175 ****
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __c_locale __old = __uselocale(_M_c_locale_ctype);
  #endif
!     wchar_t __ret = btowc(__c);
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __uselocale(__old);
  #endif
--- 169,175 ----
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __c_locale __old = __uselocale(_M_c_locale_ctype);
  #endif
!     wchar_t __ret = btowc(static_cast<unsigned char>(__c));
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __uselocale(__old);
  #endif
*************** namespace std
*** 183,191 ****
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __c_locale __old = __uselocale(_M_c_locale_ctype);
  #endif
!     mbstate_t __state;
!     memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t));
!     mbsrtowcs(__dest, &__lo, __hi - __lo, &__state);
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __uselocale(__old);
  #endif
--- 183,194 ----
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __c_locale __old = __uselocale(_M_c_locale_ctype);
  #endif
!     while (__lo < __hi)
!       {
! 	*__dest = btowc(static_cast<unsigned char>(*__lo));
! 	++__lo;
! 	++__dest;
!       }
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __uselocale(__old);
  #endif
*************** namespace std
*** 214,235 ****
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __c_locale __old = __uselocale(_M_c_locale_ctype);
  #endif
!     size_t __offset = 0;
!     while (true)
        {
! 	const wchar_t* __start = __lo + __offset;        
! 	size_t __len = __hi - __start;
! 	
! 	mbstate_t __state;
! 	memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t));
! 	size_t __con = wcsrtombs(__dest + __offset, &__start, __len, &__state);
! 	if (__con != __len && __start != 0)
! 	  {
! 	    __offset = __start - __lo;          
! 	    __dest[__offset++] = __dfault;
! 	  }
! 	else
! 	  break;
        }
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __uselocale(__old);
--- 217,228 ----
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __c_locale __old = __uselocale(_M_c_locale_ctype);
  #endif
!     while (__lo < __hi)
        {
! 	int __c = wctob(*__lo);
! 	*__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
! 	++__lo;
! 	++__dest;
        }
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __uselocale(__old);
Index: libstdc++-v3/testsuite/22_locale/ctype/narrow/wchar_t/3.cc
===================================================================
RCS file: libstdc++-v3/testsuite/22_locale/ctype/narrow/wchar_t/3.cc
diff -N libstdc++-v3/testsuite/22_locale/ctype/narrow/wchar_t/3.cc
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- libstdc++-v3/testsuite/22_locale/ctype/narrow/wchar_t/3.cc	12 Mar 2003 23:16:07 -0000
***************
*** 0 ****
--- 1,56 ----
+ // 2003-03-12  Petur Runolfsson  <peturr02 at ru dot is>
+ 
+ // Copyright (C) 2003 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 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.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ // 22.2.1.3.2 ctype<wchar_t> members
+ 
+ #include <locale>
+ #include <testsuite_hooks.h>
+ 
+ // libstdc++/9581
+ void test03()
+ {
+   using namespace std;
+   bool test = true;
+ 
+   locale loc ("se_NO.UTF-8");
+   const ctype<wchar_t>& wct = use_facet<ctype<wchar_t> >(loc);
+ 
+   const wchar_t* wstrlit = L"\x80";
+ 	
+   char buf[2];
+   wct.narrow(wstrlit, wstrlit + 2, ' ', buf);
+   VERIFY( buf[0] == wct.narrow(wstrlit[0], ' ') );
+   VERIFY( buf[1] == wct.narrow(wstrlit[1], ' ') );  
+ }
+ 
+ int main() 
+ {
+   test03();
+   return 0;
+ }
Index: libstdc++-v3/testsuite/22_locale/ctype/widen/wchar_t/2.cc
===================================================================
RCS file: libstdc++-v3/testsuite/22_locale/ctype/widen/wchar_t/2.cc
diff -N libstdc++-v3/testsuite/22_locale/ctype/widen/wchar_t/2.cc
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- libstdc++-v3/testsuite/22_locale/ctype/widen/wchar_t/2.cc	12 Mar 2003 23:16:09 -0000
***************
*** 0 ****
--- 1,54 ----
+ // 2003-03-12  Petur Runolfsson  <peturr02 at ru dot is>
+ 
+ // Copyright (C) 2003 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 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.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ // 22.2.1.3.2 ctype<wchar_t> members
+ 
+ #include <locale>
+ #include <testsuite_hooks.h>
+ 
+ // libstdc++/9870
+ void test02()
+ {
+   using namespace std;
+   bool test = true;
+ 
+   locale loc ("en_US.ISO-8859-1");
+   const ctype<wchar_t>& wct = use_facet<ctype<wchar_t> >(loc);
+ 
+   char c = 0xff;
+   wchar_t wc = wct.widen(c);
+ 
+   VERIFY( wc == static_cast<wchar_t>(0xff) );
+ }
+ 
+ int main() 
+ {
+   test02();
+   return 0;
+ }
Index: libstdc++-v3/testsuite/22_locale/ctype/widen/wchar_t/3.cc
===================================================================
RCS file: libstdc++-v3/testsuite/22_locale/ctype/widen/wchar_t/3.cc
diff -N libstdc++-v3/testsuite/22_locale/ctype/widen/wchar_t/3.cc
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- libstdc++-v3/testsuite/22_locale/ctype/widen/wchar_t/3.cc	12 Mar 2003 23:16:08 -0000
***************
*** 0 ****
--- 1,57 ----
+ // 2003-03-12  Petur Runolfsson  <peturr02 at ru dot is>
+ 
+ // Copyright (C) 2003 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 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.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ // 22.2.1.3.2 ctype<wchar_t> members
+ 
+ #include <locale>
+ #include <testsuite_hooks.h>
+ 
+ // libstdc++/9581
+ void test03()
+ {
+   using namespace std;
+   bool test = true;
+ 
+   locale loc ("se_NO.UTF-8");
+   const ctype<wchar_t>& wct = use_facet<ctype<wchar_t> >(loc);
+ 
+   const char* strlit = "\xc2\x80";
+ 	
+   wchar_t wbuf[3];
+   wct.widen(strlit, strlit + 3, wbuf);
+   VERIFY( wbuf[0] == wct.widen(strlit[0]) );
+   VERIFY( wbuf[1] == wct.widen(strlit[1]) );
+   VERIFY( wbuf[2] == wct.widen(strlit[2]) );
+ }
+ 
+ int main() 
+ {
+   test03();
+   return 0;
+ }


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