This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [v3] filebuf::setbuf match v2 behavior
- To: gcc-patches at gcc dot gnu dot org
- Subject: Re: [v3] filebuf::setbuf match v2 behavior
- From: Benjamin Kosnik <bkoz at redhat dot com>
- Date: Tue, 22 May 2001 11:30:00 -0700
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;
+ }