This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[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

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