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]

Re: [v3] filebuf::setbuf match v2 behavior



Updated patch.

2001-05-21  Benjamin Kosnik  <bkoz@redhat.com>

	* mkcheck.in (static_fail): Remove S_FLAG decoration on output.

	* include/bits/std_sstream.h (stringbuf::setbuf): Require both
	arguments to be non-null.
	* include/bits/fstream.tcc (filebuf::_M_allocate_buffers): Only
	try allocations if allocated size is greater than zero.
	(filebuf::_M_filebuf_init): Change to
	(filebuf::_M_allocate_file): Which is what it does now. 
	(filebuf::_M_allocate_bufers): Change to
	(filebuf::_M_allocate_internal_buffer): This, and create
	(filebuf::_M_allocate_pback_buffer): New.
	(filebuf::_M_destroy_internal_buffer): New.
	(filebuf::_M_buf_allocated): New data member.
	(filebuf::setbuf): Use new logic, allow use of external buffer.
	* testsuite/27_io/stringbuf_virtuals.cc: New file.
	* testsuite/27_io/filebuf_virtuals.cc: New file.

Index: mkcheck.in
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/mkcheck.in,v
retrieving revision 1.58
diff -c -p -r1.58 mkcheck.in
*** mkcheck.in	2001/05/19 20:27:36	1.58
--- mkcheck.in	2001/05/22 18:22:03
*************** test_file()
*** 393,400 ****
  
      printf "%s\t" "$RESULT"
      printf "%-2s %d\t%.3f\t%s\t%s\t%s\t%s %s\n"   \
!         "$RESULT" $C_TIME $E_TIME $TEXT $DATA $SIZE $NAME "$S_FLAG"    \
!         >> $RESULTS_FILE
  }
  
  setup_size_command
--- 393,399 ----
  
      printf "%s\t" "$RESULT"
      printf "%-2s %d\t%.3f\t%s\t%s\t%s\t%s %s\n"   \
!         "$RESULT" $C_TIME $E_TIME $TEXT $DATA $SIZE $NAME >> $RESULTS_FILE
  }
  
  setup_size_command
Index: include/bits/fstream.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/fstream.tcc,v
retrieving revision 1.13
diff -c -p -r1.13 fstream.tcc
*** fstream.tcc	2001/05/08 03:07:56	1.13
--- fstream.tcc	2001/05/22 18:22:05
*************** namespace std
*** 39,45 ****
    template<typename _CharT, typename _Traits>
      void
      basic_filebuf<_CharT, _Traits>::
!     _M_filebuf_init()
      {
        if (!_M_file)
  	{
--- 39,45 ----
    template<typename _CharT, typename _Traits>
      void
      basic_filebuf<_CharT, _Traits>::
!     _M_allocate_file()
      {
        if (!_M_file)
  	{
*************** namespace std
*** 57,67 ****
    template<typename _CharT, typename _Traits>
      void
      basic_filebuf<_CharT, _Traits>::
!     _M_allocate_buffers()
      {
!       if (!_M_buf)
  	{
  	  _M_buf_size = _M_buf_size_opt;
  	  // Allocate internal buffer.
  	  try { _M_buf = new char_type[_M_buf_size]; }
  	  catch(...) 
--- 57,68 ----
    template<typename _CharT, typename _Traits>
      void
      basic_filebuf<_CharT, _Traits>::
!     _M_allocate_internal_buffer()
      {
!       if (!_M_buf && _M_buf_size_opt)
  	{
  	  _M_buf_size = _M_buf_size_opt;
+ 
  	  // Allocate internal buffer.
  	  try { _M_buf = new char_type[_M_buf_size]; }
  	  catch(...) 
*************** namespace std
*** 69,75 ****
  	      delete [] _M_buf;
  	      __throw_exception_again;
  	    }
! 	  
  	  // Allocate pback buffer.
  	  try 
  	    { _M_pback = new char_type[_M_pback_size]; }
--- 70,102 ----
  	      delete [] _M_buf;
  	      __throw_exception_again;
  	    }
! 	  _M_buf_allocated = true;
! 	}
!     }
! 
!   // Both close and setbuf need to deallocate internal buffers, if it exists.
!   template<typename _CharT, typename _Traits>
!     void
!     basic_filebuf<_CharT, _Traits>::
!     _M_destroy_internal_buffer()
!     {
!       if (_M_buf_allocated)
! 	{
! 	  delete [] _M_buf;
! 	  _M_buf = NULL;
! 	  _M_buf_allocated = false;
! 	  this->setg(NULL, NULL, NULL);
! 	  this->setp(NULL, NULL);
! 	}
!     }
! 
!  template<typename _CharT, typename _Traits>
!     void
!     basic_filebuf<_CharT, _Traits>::
!     _M_allocate_pback_buffer()
!     {
!       if (!_M_pback && _M_pback_size)
! 	{
  	  // Allocate pback buffer.
  	  try 
  	    { _M_pback = new char_type[_M_pback_size]; }
*************** namespace std
*** 85,100 ****
      basic_filebuf<_CharT, _Traits>::
      basic_filebuf() 
      : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()), 
!     _M_state_beg(__state_type()), _M_last_overflowed(false)
      { }
  
    template<typename _CharT, typename _Traits>
      basic_filebuf<_CharT, _Traits>::
      basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, int_type __s)
      : __streambuf_type(),  _M_file(NULL), _M_state_cur(__state_type()), 
!     _M_state_beg(__state_type()), _M_last_overflowed(false)
      {
!       _M_filebuf_init();
        _M_file->sys_open(__f, __mode);
        if (this->is_open())
  	{
--- 112,129 ----
      basic_filebuf<_CharT, _Traits>::
      basic_filebuf() 
      : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()), 
!     _M_state_beg(__state_type()), _M_buf_allocated(false), 
!     _M_last_overflowed(false)
      { }
  
    template<typename _CharT, typename _Traits>
      basic_filebuf<_CharT, _Traits>::
      basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, int_type __s)
      : __streambuf_type(),  _M_file(NULL), _M_state_cur(__state_type()), 
!     _M_state_beg(__state_type()), _M_buf_allocated(false), 
!     _M_last_overflowed(false)
      {
!       _M_allocate_file();
        _M_file->sys_open(__f, __mode);
        if (this->is_open())
  	{
*************** namespace std
*** 102,110 ****
  	  if (__s)
  	    {
  	      _M_buf_size_opt = __s;
! 	      _M_allocate_buffers();
  	      _M_set_indeterminate();
  	    }
  	}
      }
  
--- 131,140 ----
  	  if (__s)
  	    {
  	      _M_buf_size_opt = __s;
! 	      _M_allocate_internal_buffer();
  	      _M_set_indeterminate();
  	    }
+ 	  _M_allocate_pback_buffer();
  	}
      }
  
*************** namespace std
*** 116,126 ****
        __filebuf_type *__ret = NULL;
        if (!this->is_open())
  	{
! 	  _M_filebuf_init();
  	  _M_file->open(__s, __mode);
  	  if (this->is_open())
  	    {
! 	      _M_allocate_buffers();
  	      _M_mode = __mode;
  	      
  	      // For time being, set both (in/out) sets  of pointers.
--- 146,157 ----
        __filebuf_type *__ret = NULL;
        if (!this->is_open())
  	{
! 	  _M_allocate_file();
  	  _M_file->open(__s, __mode);
  	  if (this->is_open())
  	    {
! 	      _M_allocate_internal_buffer();
! 	      _M_allocate_pback_buffer();
  	      _M_mode = __mode;
  	      
  	      // For time being, set both (in/out) sets  of pointers.
*************** namespace std
*** 159,172 ****
  #endif
  
  	  _M_mode = ios_base::openmode(0);
! 	  if (_M_buf)
  	    {
- 	      delete [] _M_buf;
- 	      _M_buf = NULL;
  	      delete [] _M_pback;
  	      _M_pback = NULL;
- 	      this->setg(NULL, NULL, NULL);
- 	      this->setp(NULL, NULL);
  	    }
  	  __ret = this;
  	}
--- 190,201 ----
  #endif
  
  	  _M_mode = ios_base::openmode(0);
! 	  _M_destroy_internal_buffer();
! 
! 	  if (_M_pback)
  	    {
  	      delete [] _M_pback;
  	      _M_pback = NULL;
  	    }
  	  __ret = this;
  	}
*************** namespace std
*** 432,437 ****
--- 461,494 ----
        return __ret;
      }
  
+   template<typename _CharT, typename _Traits>
+     basic_filebuf<_CharT, _Traits>::__streambuf_type* 
+     basic_filebuf<_CharT, _Traits>::
+     setbuf(char_type* __s, streamsize __n)
+     {
+       if (!this->is_open() && __s == 0 && __n == 0)
+ 	_M_buf_size_opt = 0;
+       else if (__s && __n)
+ 	{
+ 	  // This is implementation-defined behavior, and assumes
+ 	  // that an external char_type array of length (__s + __n)
+ 	  // exists and has been pre-allocated. If this is not the
+ 	  // case, things will quickly blow up.
+ 	  // Step 1: Destroy the current internal array.
+ 	  _M_destroy_internal_buffer();
+ 	  
+ 	  // Step 2: Use the external array.
+ 	  _M_buf = __s;
+ 	  _M_buf_size_opt = _M_buf_size = __n;
+ 	  _M_set_indeterminate();
+ 	  
+ 	// Step 3: Make sure a pback buffer is allocated.
+ 	  _M_allocate_pback_buffer();
+ 	}
+       _M_last_overflowed = false;	
+       return this; 
+     }
+   
    template<typename _CharT, typename _Traits>
      basic_filebuf<_CharT, _Traits>::pos_type
      basic_filebuf<_CharT, _Traits>::
Index: include/bits/std_fstream.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/std_fstream.h,v
retrieving revision 1.8
diff -c -p -r1.8 std_fstream.h
*** std_fstream.h	2001/05/08 03:07:56	1.8
--- std_fstream.h	2001/05/22 18:22:06
*************** namespace std 
*** 78,83 ****
--- 78,86 ----
        // MT lock inherited from libio or other low-level io library.
        __c_lock          	_M_lock;
  
+       // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer..
+       bool			_M_buf_allocated;
+ 
        // XXX Needed? 
        bool			_M_last_overflowed;  
    
*************** namespace std 
*** 107,119 ****
        close(void);
  
      protected:
!       // Allocate up pback and internal buffers.
        void 
!       _M_allocate_buffers();
  
        // Create __file_type object and initialize it properly.
        void
!       _M_filebuf_init();
  
        // Overridden virtual functions:
        virtual streamsize 
--- 110,127 ----
        close(void);
  
      protected:
!       void 
!       _M_allocate_internal_buffer();
! 
        void 
!       _M_destroy_internal_buffer();
  
+       void 
+       _M_allocate_pback_buffer();
+ 
        // Create __file_type object and initialize it properly.
        void
!       _M_allocate_file();
  
        // Overridden virtual functions:
        virtual streamsize 
*************** namespace std 
*** 151,166 ****
        _M_really_overflow(int_type __c = _Traits::eof());
      
        virtual __streambuf_type* 
!       setbuf(char_type* __s, streamsize __n)
!       {
! 	if (!this->is_open() && __s == 0 && __n == 0)
! 	  {
! 	    _M_buf_size = 0;
! 	    _M_buf_size_opt = 0;
! 	  }
! 	_M_last_overflowed = false;	
! 	return this; 
!       }
      
        virtual pos_type 
        seekoff(off_type __off, ios_base::seekdir __way,
--- 159,165 ----
        _M_really_overflow(int_type __c = _Traits::eof());
      
        virtual __streambuf_type* 
!       setbuf(char_type* __s, streamsize __n);
      
        virtual pos_type 
        seekoff(off_type __off, ios_base::seekdir __way,
Index: include/bits/std_sstream.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/std_sstream.h,v
retrieving revision 1.4
diff -c -p -r1.4 std_sstream.h
*** std_sstream.h	2001/05/02 05:50:19	1.4
--- std_sstream.h	2001/05/22 18:22:07
*************** namespace std
*** 143,149 ****
        virtual __streambuf_type* 
        setbuf(char_type* __s, streamsize __n)
        { 
! 	if (__n) 
  	  {
  	    _M_string = __string_type(__s, __n);
  	    _M_really_sync(0, 0);
--- 143,149 ----
        virtual __streambuf_type* 
        setbuf(char_type* __s, streamsize __n)
        { 
! 	if (__s && __n) 
  	  {
  	    _M_string = __string_type(__s, __n);
  	    _M_really_sync(0, 0);
Index: testsuite/27_io/filebuf_virtuals.cc
===================================================================
RCS file: filebuf_virtuals.cc
diff -N filebuf_virtuals.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- filebuf_virtuals.cc	Tue May 22 11:22:09 2001
***************
*** 0 ****
--- 1,62 ----
+ // 2001-05-21 Benjamin Kosnik  <bkoz@redhat.com>
+ 
+ // Copyright (C) 2001 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 <debug_assert.h>
+ 
+ void test01()
+ {
+   using namespace std;
+ 
+   bool test = true;
+   char buf[512];
+   const char* strlit = "how to tell a story and other essays: mark twain";
+   const size_t strlitsize = strlen(strlit);
+   filebuf fbuf01;
+ 
+   fbuf01.pubsetbuf(buf, 512);
+   fbuf01.sputn(strlit, strlitsize);
+   VERIFY( strncmp(strlit, buf, strlitsize) != 0 );
+ }
+ 
+ void test02()
+ {
+   using namespace std;
+ 
+   bool test = true;
+   char buf[512];
+   const char* strlit = "how to tell a story and other essays: mark twain";
+   const size_t strlitsize = strlen(strlit);
+   filebuf fbuf01;
+   fbuf01.open("tmp", ios_base::out);
+ 
+   fbuf01.pubsetbuf(buf, strlitsize);
+   fbuf01.sputn(strlit, strlitsize);
+   VERIFY( strncmp(strlit, buf, strlitsize) == 0 );
+ }
+ 
+ main() 
+ {
+   test01();
+   test02();
+   return 0;
+ }
Index: testsuite/27_io/stringbuf_virtuals.cc
===================================================================
RCS file: stringbuf_virtuals.cc
diff -N stringbuf_virtuals.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- stringbuf_virtuals.cc	Tue May 22 11:22:09 2001
***************
*** 0 ****
--- 1,46 ----
+ // 2001-05-21 Benjamin Kosnik  <bkoz@redhat.com>
+ 
+ // Copyright (C) 2001 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.7.1.3 Overridden virtual functions
+ 
+ #include <sstream>
+ #include <debug_assert.h>
+ 
+ void test01()
+ {
+   using namespace std;
+ 
+   bool test = true;
+   char buf[512];
+   const char* strlit = "how to tell a story and other essays: mark twain";
+   const size_t strlitsize = strlen(strlit);
+   stringbuf sbuf(ios_base::out);
+ 
+   sbuf.pubsetbuf(buf, strlitsize);
+   sbuf.sputn(strlit, strlitsize);
+   VERIFY( strncmp(strlit, buf, strlitsize) != 0 );
+ }
+ 
+ int main() 
+ {
+   test01();
+ 
+   return 0;
+ }


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