This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix libstdc++/9581 and libstdc++/9870
- From: Pétur Runólfsson <peturr02 at ru dot is>
- To: <libstdc++ at gcc dot gnu dot org>
- Cc: <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 13 Mar 2003 09:27:28 -0000
- Subject: [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;
+ }