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++/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

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