This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Fix libstdc++/13582
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Fri, 09 Jan 2004 10:29:18 +0100
- Subject: [Patch] Fix libstdc++/13582
Whee!
Basically, I have implemented Pétur's notes present in the audit
trail of 12868: we can exploit the external buffer in order to imbue
'on the fly' a new locale without trying to seek back (not a good
idea for pipes and ttys ;)
I think that the final result is sufficiently clean: just an additional
|| in underflow to teach it that since we have just imbued a new locale
we should first try to simply convert the remainder and delay low level
reads (this case is characterized by !_M_reading and __remainder > 0
whereas, usually, !_M_reading implies __remainder == 0: at the beginning
of a series of gets we cannot have a remainder)
Tested x86-linux. Will wait the usual 24 hours or so.
Paolo.
P.S. Well, I would like to remark that apparently our strong competitor
on x86 does bad on most of our recent QoI testcases for filebuf::imbue :)
///////////////
2004-01-09 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/wchar_t/13582-2.cc: New.
* testsuite/27_io/objects/wchar_t/13582-1_xin.cc: Likewise.
* testsuite/27_io/objects/wchar_t/13582-1_xin.in: Likewise.
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 Fri Jan 9 00:54:34 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
*** 221,228 ****
__rlen = __buflen;
}
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)
--- 221,232 ----
__rlen = __buflen;
}
const streamsize __remainder = _M_ext_end - _M_ext_next;
! // Normally, either __remainder == 0 and !_M_reading or viceversa.
! // An imbue in 'read' mode, however, implies first converting the
! // external chars already present.
! __rlen = __rlen <= __remainder
! || (!_M_reading && __remainder) ? 0 : __rlen - __remainder;
!
// Allocate buffer if necessary and move unconverted
// bytes to front.
if (_M_ext_buf_size < __blen)
*************** namespace std
*** 738,753 ****
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);
--- 742,775 ----
basic_filebuf<_CharT, _Traits>::
imbue(const locale& __loc)
{
! bool __testvalid = true;
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())
! __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());
! _M_reading = false;
! _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)
{
if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
_M_codecvt = &use_facet<__codecvt_type>(__loc);
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 Fri Jan 9 10:17:48 2004
***************
*** 0 ****
--- 1,79 ----
+ // 2004-01-09 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 <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 == WEOF );
+ }
+
+ 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 Fri Jan 9 09:46:33 2004
***************
*** 0 ****
--- 1,61 ----
+ // 2004-01-09 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 Fri Jan 9 01:30:56 2004
***************
*** 0 ****
--- 1 ----
+ 12345