This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] Fix libstdc++/13582
- From: Paolo Carlini <pcarlini at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 11 Jan 2004 16:20:31 +0100
- Subject: [v3] Fix libstdc++/13582
Hi,
this is what I have eventually committed.
Tested x86-linux.
Paolo.
///////////////
2004-01-11 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/13582
* include/bits/fstream.tcc (imbue): Exploit the external
buffer to imbue 'on the fly' a new locale and convert its
remainder with the new codecvt facet.
(underflow): Tweak slightly to deal with this special case.
* testsuite/27_io/basic_filebuf/imbue/char/13582-2.cc: New.
* testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-2.cc: Ditto.
* testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc: Ditto.
* testsuite/27_io/objects/wchar_t/13582-1_xin.cc: Ditto.
* testsuite/27_io/objects/wchar_t/13582-1_xin.in: Ditto.
diff -prN libstdc++-v3-orig/include/bits/fstream.tcc libstdc++-v3/include/bits/fstream.tcc
*** libstdc++-v3-orig/include/bits/fstream.tcc Wed Dec 10 21:05:00 2003
--- libstdc++-v3/include/bits/fstream.tcc Sun Jan 11 10:00:02 2004
***************
*** 1,6 ****
// File based streams -*- C++ -*-
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
--- 1,6 ----
// File based streams -*- C++ -*-
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
*************** namespace std
*** 171,177 ****
}
return __ret;
}
!
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::int_type
basic_filebuf<_CharT, _Traits>::
--- 171,177 ----
}
return __ret;
}
!
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::int_type
basic_filebuf<_CharT, _Traits>::
*************** namespace std
*** 222,241 ****
}
const streamsize __remainder = _M_ext_end - _M_ext_next;
__rlen = __rlen > __remainder ? __rlen - __remainder : 0;
!
// Allocate buffer if necessary and move unconverted
// bytes to front.
if (_M_ext_buf_size < __blen)
{
char* __buf = new char[__blen];
! if (__remainder > 0)
std::memcpy(__buf, _M_ext_next, __remainder);
delete [] _M_ext_buf;
_M_ext_buf = __buf;
_M_ext_buf_size = __blen;
}
! else if (__remainder > 0)
std::memmove(_M_ext_buf, _M_ext_next, __remainder);
_M_ext_next = _M_ext_buf;
--- 222,246 ----
}
const streamsize __remainder = _M_ext_end - _M_ext_next;
__rlen = __rlen > __remainder ? __rlen - __remainder : 0;
!
! // An imbue in 'read' mode implies first converting the external
! // chars already present.
! if (_M_reading && this->egptr() == this->eback() && __remainder)
! __rlen = 0;
!
// Allocate buffer if necessary and move unconverted
// bytes to front.
if (_M_ext_buf_size < __blen)
{
char* __buf = new char[__blen];
! if (__remainder)
std::memcpy(__buf, _M_ext_next, __remainder);
delete [] _M_ext_buf;
_M_ext_buf = __buf;
_M_ext_buf_size = __blen;
}
! else if (__remainder)
std::memmove(_M_ext_buf, _M_ext_next, __remainder);
_M_ext_next = _M_ext_buf;
*************** namespace std
*** 738,759 ****
basic_filebuf<_CharT, _Traits>::
imbue(const locale& __loc)
{
! bool __testfail = false;
! if (this->is_open())
! {
! const pos_type __ret = this->seekoff(0, ios_base::cur,
! this->_M_mode);
! const bool __teststate = __check_facet(_M_codecvt).encoding() == -1;
! __testfail = __teststate && __ret != pos_type(off_type(0));
! }
! if (!__testfail)
{
! if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
! _M_codecvt = &use_facet<__codecvt_type>(__loc);
else
! _M_codecvt = 0;
}
}
// Inhibit implicit instantiations for required instantiations,
--- 743,794 ----
basic_filebuf<_CharT, _Traits>::
imbue(const locale& __loc)
{
! bool __testvalid = true;
!
! const __codecvt_type* _M_codecvt_tmp = 0;
! if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
! _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
! if (this->is_open())
{
! // encoding() == -1 is ok only at the beginning.
! if ((_M_reading || _M_writing)
! && __check_facet(_M_codecvt).encoding() == -1)
! __testvalid = false;
else
! {
! if (_M_reading)
! {
! if (__check_facet(_M_codecvt).always_noconv())
! {
! if (_M_codecvt_tmp
! && !__check_facet(_M_codecvt_tmp).always_noconv())
! __testvalid = this->seekoff(0, ios_base::cur, this->_M_mode)
! != pos_type(off_type(-1));
! }
! else
! {
! // External position corresponding to gptr().
! _M_ext_next = _M_ext_buf
! + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
! this->gptr() - this->eback());
! const streamsize __remainder = _M_ext_end - _M_ext_next;
! if (__remainder)
! std::memmove(_M_ext_buf, _M_ext_next, __remainder);
!
! _M_ext_next = _M_ext_buf;
! _M_ext_end = _M_ext_buf + __remainder;
! _M_set_buffer(-1);
! _M_state_last = _M_state_cur = _M_state_beg;
! }
! }
! else if (_M_writing && (__testvalid = _M_terminate_output()))
! _M_set_buffer(-1);
! }
}
+
+ if (__testvalid)
+ _M_codecvt = _M_codecvt_tmp;
}
// Inhibit implicit instantiations for required instantiations,
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_filebuf/imbue/char/13582-2.cc libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13582-2.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_filebuf/imbue/char/13582-2.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13582-2.cc Sun Jan 11 09:58:59 2004
***************
*** 0 ****
--- 1,80 ----
+ // 2004-01-11 Petur Runolfsson <peturr02@ru.is>
+
+ // Copyright (C) 2004 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.
+
+ // 27.8.1.4 Overridden virtual functions
+
+ #include <fstream>
+ #include <locale>
+
+ #include <unistd.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+
+ #include <testsuite_hooks.h>
+
+ // libstdc++/13582
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+ using namespace std;
+
+ locale loc_en(__gnu_test::try_named_locale("en_US"));
+ locale loc_fr(__gnu_test::try_named_locale("fr_FR"));
+
+ const char* name = "tmp_fifo_13582-2";
+ unlink(name);
+ mkfifo(name, S_IRWXU);
+
+ int child = fork();
+ if (child == 0)
+ {
+ filebuf fbout;
+ fbout.open(name, ios_base::out);
+ fbout.sputn("12345", 5);
+ fbout.pubsync();
+ sleep(2);
+ fbout.close();
+ exit(0);
+ }
+
+ filebuf fbin;
+ fbin.open(name, ios_base::in);
+ sleep(1);
+ filebuf::int_type n = fbin.sbumpc();
+ VERIFY( n == '1' );
+ fbin.pubimbue(loc_en);
+ n = fbin.sbumpc();
+ VERIFY( n == '2' );
+ fbin.pubimbue(loc_fr);
+ n = fbin.sbumpc();
+ VERIFY( n == '3' );
+ n = fbin.sbumpc();
+ VERIFY( n == '4' );
+ n = fbin.sbumpc();
+ VERIFY( n == '5' );
+ n = fbin.sbumpc();
+ VERIFY( n == filebuf::traits_type::eof() );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-2.cc libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-2.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-2.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-2.cc Sun Jan 11 09:59:13 2004
***************
*** 0 ****
--- 1,80 ----
+ // 2004-01-11 Petur Runolfsson <peturr02@ru.is>
+
+ // Copyright (C) 2004 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.
+
+ // 27.8.1.4 Overridden virtual functions
+
+ #include <fstream>
+ #include <locale>
+
+ #include <unistd.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+
+ #include <testsuite_hooks.h>
+
+ // libstdc++/13582
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+ using namespace std;
+
+ locale loc_en(__gnu_test::try_named_locale("en_US"));
+ locale loc_fr(__gnu_test::try_named_locale("fr_FR"));
+
+ const char* name = "tmp_fifo_13582-2";
+ unlink(name);
+ mkfifo(name, S_IRWXU);
+
+ int child = fork();
+ if (child == 0)
+ {
+ filebuf fbout;
+ fbout.open(name, ios_base::out);
+ fbout.sputn("12345", 5);
+ fbout.pubsync();
+ sleep(2);
+ fbout.close();
+ exit(0);
+ }
+
+ wfilebuf fbin;
+ fbin.open(name, ios_base::in);
+ sleep(1);
+ wfilebuf::int_type n = fbin.sbumpc();
+ VERIFY( n == L'1' );
+ fbin.pubimbue(loc_en);
+ n = fbin.sbumpc();
+ VERIFY( n == L'2' );
+ fbin.pubimbue(loc_fr);
+ n = fbin.sbumpc();
+ VERIFY( n == L'3' );
+ n = fbin.sbumpc();
+ VERIFY( n == L'4' );
+ n = fbin.sbumpc();
+ VERIFY( n == L'5' );
+ n = fbin.sbumpc();
+ VERIFY( n == wfilebuf::traits_type::eof() );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc Sun Jan 11 09:58:20 2004
***************
*** 0 ****
--- 1,72 ----
+ // 2004-01-11 Petur Runolfsson <peturr02@ru.is>
+
+ // Copyright (C) 2004 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.
+
+ // 27.8.1.4 Overridden virtual functions
+
+ #include <fstream>
+ #include <locale>
+ #include <testsuite_hooks.h>
+
+ // libstdc++/13582
+ int test01()
+ {
+ bool test __attribute__((unused)) = true;
+ using namespace std;
+
+ locale loc_en(__gnu_test::try_named_locale("en_US"));
+ locale loc_fr(__gnu_test::try_named_locale("fr_FR"));
+
+ const char* name = "tmp_13582-3.tst";
+
+ {
+ filebuf fbout;
+ fbout.open(name, ios_base::out);
+ fbout.sputn("AbCdE", 5);
+ fbout.close();
+ }
+
+ {
+ wfilebuf fbin;
+ fbin.open(name, ios_base::in);
+ wfilebuf::int_type n = fbin.sbumpc();
+ VERIFY( n == L'A' );
+ fbin.pubimbue(loc_en);
+ fbin.pubseekoff(0, ios_base::cur);
+ n = fbin.sbumpc();
+ VERIFY( n == L'b' );
+ fbin.pubimbue(loc_fr);
+ n = fbin.sbumpc();
+ VERIFY( n == L'C' );
+ n = fbin.sbumpc();
+ VERIFY( n == L'd' );
+ fbin.pubseekoff(0, ios_base::cur);
+ n = fbin.sbumpc();
+ VERIFY( n == L'E' );
+ n = fbin.sbumpc();
+ VERIFY( n == wfilebuf::traits_type::eof() );
+ fbin.close();
+ }
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/objects/wchar_t/13582-1_xin.cc libstdc++-v3/testsuite/27_io/objects/wchar_t/13582-1_xin.cc
*** libstdc++-v3-orig/testsuite/27_io/objects/wchar_t/13582-1_xin.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/objects/wchar_t/13582-1_xin.cc Sun Jan 11 09:58:20 2004
***************
*** 0 ****
--- 1,61 ----
+ // 2004-01-11 Petur Runolfsson <peturr02@ru.is>
+
+ // Copyright (C) 2004 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.
+
+ #include <iostream>
+ #include <string>
+ #include <locale>
+
+ // libstdc++/13582
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+ using namespace std;
+
+ ios_base::sync_with_stdio(false);
+ wcout << "Type in 12345\n";
+
+ wstring str;
+ wchar_t c;
+
+ if (wcin.get(c) && !isspace(c, wcin.getloc()))
+ {
+ str.push_back(c);
+ wcin.imbue(locale("en_US"));
+ }
+
+ if (wcin.get(c) && !isspace(c, wcin.getloc()))
+ {
+ str.push_back(c);
+ wcin.imbue(locale("fr_FR"));
+ }
+
+ while (wcin.get(c) && !isspace(c, wcin.getloc()))
+ {
+ str.push_back(c);
+ }
+
+ wcout << str << endl;
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/objects/wchar_t/13582-1_xin.in libstdc++-v3/testsuite/27_io/objects/wchar_t/13582-1_xin.in
*** libstdc++-v3-orig/testsuite/27_io/objects/wchar_t/13582-1_xin.in Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/objects/wchar_t/13582-1_xin.in Sun Jan 11 09:58:20 2004
***************
*** 0 ****
--- 1 ----
+ 12345