diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index afd5f672699a3d6adef967409d0d3e29e816b500..7165b8e6cc87d201e418ef75b5bef0112d5345cf 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2003-05-26 Benjamin Kosnik <bkoz@redhat.com> + + PR libstdc++/9339 + * include/std/std_fstream.h (basic_filebuf::_M_overflow): Remove. + (_M_pback): No array necessary. + * include/bits/fstream.tcc (basic_filebuf::_M_overflow): Add + unbuffered case, coalesec into ... + (basic_filebuf::overflow): ...this. + * testsuite/27_io/basic_filebuf/sputn/char/9339.cc: New. + * testsuite/27_io/basic_filebuf/sputc/char/2.cc: Unbuffered. + 2003-05-24 Nathanael Nerode <neroden@gcc.gnu.org> * libsupc++/Makefile.am, libsupc++/cxxabi.h, libsupc++/del_op.cc, @@ -58,6 +69,7 @@ 2003-05-22 Brad Spencer <spencer@infointeractive.com> + PR libstdc++/10106 * configure.in: Add Solaris cross bits. 2003-05-21 Danny Smith <dannysmith@users.sourceforge.net> diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index cda0bacd9f9cf7f7f711b1ca9081edfcd17834fb..9bbb5cc1a52927f28322110aff6ccce51bd70ca1 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -73,7 +73,7 @@ namespace std basic_filebuf() : __streambuf_type(), _M_file(&_M_lock), _M_state_cur(__state_type()), _M_state_beg(__state_type()), _M_buf(NULL), _M_buf_size(BUFSIZ), _M_buf_allocated(false), - _M_last_overflowed(false), _M_pback_cur_save(0), + _M_last_overflowed(false), _M_filepos(0), _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false), _M_codecvt(0) { this->_M_buf_unified = true; @@ -125,7 +125,7 @@ namespace std const bool __testput = this->_M_out_beg < this->_M_out_lim; if (__testput - && traits_type::eq_int_type(_M_overflow(__eof), __eof)) + && traits_type::eq_int_type(this->overflow(), __eof)) __testfail = true; #if 0 @@ -133,7 +133,7 @@ namespace std if (_M_last_overflowed) { _M_output_unshift(); - _M_overflow(__eof); + this->overflow(); } #endif } @@ -204,7 +204,7 @@ namespace std // Sync internal and external buffers. if (__testout && this->_M_out_beg < this->_M_out_lim) - _M_overflow(); + this->overflow(); if (_M_buf_size > 1) { @@ -321,67 +321,49 @@ namespace std return __ret; } - template<typename _CharT, typename _Traits> - typename basic_filebuf<_CharT, _Traits>::int_type - basic_filebuf<_CharT, _Traits>:: - _M_overflow(int_type __c) - { - int_type __ret = traits_type::eof(); - const bool __testeof = traits_type::eq_int_type(__c, __ret); - const bool __testput = this->_M_out_beg < this->_M_out_lim; - - if (__testput) - { - // Need to restore current position. The position of the - // external byte sequence (_M_file) corresponds to - // _M_filepos, and we need to move it to _M_out_beg for the - // write. - if (_M_filepos != this->_M_out_beg) - _M_file.seekoff(this->_M_out_beg - _M_filepos, ios_base::cur); - - // If appropriate, append the overflow char. - if (!__testeof) - *this->_M_out_lim++ = traits_type::to_char_type(__c); - - // Convert pending sequence to external representation, - // output. - if (_M_convert_to_external(this->_M_out_beg, - this->_M_out_lim - this->_M_out_beg) - && (!__testeof || (__testeof && !_M_file.sync()))) - { - _M_set_buffer(0); - __ret = traits_type::not_eof(__c); - } - } - _M_last_overflowed = true; - return __ret; - } - template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>:: overflow(int_type __c) { int_type __ret = traits_type::eof(); - const bool __testput = this->_M_out_cur < this->_M_out_end; + const bool __testeof = traits_type::eq_int_type(__c, __ret); const bool __testout = this->_M_mode & ios_base::out; - // Perhaps set below in _M_overflow. - _M_last_overflowed = false; - if (__testout) { - if (traits_type::eq_int_type(__c, traits_type::eof())) - __ret = traits_type::not_eof(__c); - else if (__testput) + if (this->_M_out_beg < this->_M_out_lim) + { + // Need to restore current position. The position of the + // external byte sequence (_M_file) corresponds to + // _M_filepos, and we need to move it to _M_out_beg for + // the write. + if (_M_filepos != this->_M_out_beg) + _M_file.seekoff(this->_M_out_beg - _M_filepos, ios_base::cur); + + // If appropriate, append the overflow char. + if (!__testeof) + *this->_M_out_lim++ = traits_type::to_char_type(__c); + + // Convert pending sequence to external representation, + // output. + if (_M_convert_to_external(this->_M_out_beg, + this->_M_out_lim - this->_M_out_beg) + && (!__testeof || (__testeof && !_M_file.sync()))) + { + _M_set_buffer(0); + __ret = traits_type::not_eof(__c); + } + } + else { - *this->_M_out_cur = traits_type::to_char_type(__c); - _M_move_out_cur(1); - __ret = traits_type::not_eof(__c); + // Unbuffered. + char_type __conv = traits_type::to_char_type(__c); + if (!__testeof && _M_convert_to_external(&__conv, 1)) + __ret = __c; } - else - __ret = this->_M_overflow(__c); } + _M_last_overflowed = true; return __ret; } diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc index f80a815aa42723293798026e4faea9a84c52290c..5b76c40f9288c85d77f47eb8aa028d6ca27cef2d 100644 --- a/libstdc++-v3/include/bits/streambuf.tcc +++ b/libstdc++-v3/include/bits/streambuf.tcc @@ -115,7 +115,7 @@ namespace std while (__ret < __n) { const size_t __buf_len = _M_in_end - _M_in_cur; - if (__buf_len > 0) + if (__buf_len) { const size_t __remaining = __n - __ret; const size_t __len = std::min(__buf_len, __remaining); @@ -149,7 +149,7 @@ namespace std while (__ret < __n) { const size_t __buf_len = _M_out_end - _M_out_cur; - if (__buf_len > 0) + if (__buf_len) { const size_t __remaining = __n - __ret; const size_t __len = std::min(__buf_len, __remaining); @@ -161,7 +161,7 @@ namespace std if (__ret < __n) { - const int_type __c = this->overflow(traits_type::to_int_type(*__s)); + int_type __c = this->overflow(traits_type::to_int_type(*__s)); if (!traits_type::eq_int_type(__c, traits_type::eof())) { ++__ret; diff --git a/libstdc++-v3/include/std/std_fstream.h b/libstdc++-v3/include/std/std_fstream.h index 27794881c75d5e1e7b491df70b6dabdfa3a3c86c..9faf73730062947996d42b69e3ff53ec0e20f832 100644 --- a/libstdc++-v3/include/std/std_fstream.h +++ b/libstdc++-v3/include/std/std_fstream.h @@ -158,7 +158,7 @@ namespace std * @note pbacks of over one character are not currently supported. * @endif */ - char_type _M_pback[1]; + char_type _M_pback; char_type* _M_pback_cur_save; char_type* _M_pback_end_save; bool _M_pback_init; @@ -177,7 +177,7 @@ namespace std { _M_pback_cur_save = this->_M_in_cur; _M_pback_end_save = this->_M_in_end; - this->setg(_M_pback, _M_pback, _M_pback + 1); + this->setg(&_M_pback, &_M_pback, &_M_pback + 1); _M_pback_init = true; } } @@ -191,8 +191,8 @@ namespace std if (_M_pback_init) { // Length _M_in_cur moved in the pback buffer. - const size_t __off_cur = this->_M_in_cur - _M_pback; - this->setg(this->_M_buf, _M_pback_cur_save + __off_cur, + const size_t __off = this->_M_in_cur == &_M_pback ? 0 : 1; + this->setg(this->_M_buf, _M_pback_cur_save + __off, _M_pback_end_save); _M_pback_init = false; } @@ -311,19 +311,6 @@ namespace std virtual int_type pbackfail(int_type __c = _Traits::eof()); - // NB: For what the standard expects of the overflow function, - // see _M_overflow(), below. Because basic_streambuf's - // sputc/sputn call overflow directly, and the complications of - // this implementation's setting of the initial pointers all - // equal to _M_buf when initializing, it seems essential to have - // this in actuality be a helper function that checks for the - // eccentricities of this implementation, and then call - // overflow() if indeed the buffer is full. - - // [documentation is inherited] - virtual int_type - overflow(int_type __c = _Traits::eof()); - // Stroustrup, 1998, p 648 // The overflow() function is called to transfer characters to the // real output destination when the buffer is full. A call to @@ -336,8 +323,8 @@ namespace std * @doctodo * @endif */ - int_type - _M_overflow(int_type __c = _Traits::eof()); + virtual int_type + overflow(int_type __c = _Traits::eof()); // Convert internal byte sequence to external, char-based // sequence via codecvt. @@ -389,7 +376,7 @@ namespace std off_type __off = this->_M_out_cur - this->_M_out_lim; // _M_file.sync() will be called within - if (traits_type::eq_int_type(_M_overflow(), traits_type::eof())) + if (traits_type::eq_int_type(this->overflow(), traits_type::eof())) __ret = -1; else if (__off) _M_file.seekoff(__off, ios_base::cur); @@ -444,7 +431,7 @@ namespace std // This function sets the pointers of the internal buffer, both get // and put areas. Typically, __off == _M_in_end - _M_in_beg upon - // _M_underflow; __off == 0 upon _M_overflow, seekoff, open, setbuf. + // _M_underflow; __off == 0 upon overflow, seekoff, open, setbuf. // // NB: _M_out_end - _M_out_beg == _M_buf_size - 1, since _M_buf_size // reflects the actual allocated memory and the last cell is reserved diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sputc/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputc/char/2.cc new file mode 100644 index 0000000000000000000000000000000000000000..f6a4ae8b0db37e230c37a0f4ca0d7fe485c47523 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputc/char/2.cc @@ -0,0 +1,129 @@ +// 2003-05-21 Benjamin Kosnik <bkoz@redhat.com> + +// Copyright (C) 2003 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 <testsuite_hooks.h> + +// @require@ %-*.tst %-*.txt +// @diff@ %-*.tst %*.txt + +// NB: This test assumes that _M_buf_size == 40, and not the usual +// buffer_size length of BUFSIZ (8192), so that overflow/underflow can be +// simulated a bit more readily. +// NRB (Nota Really Bene): setting it to 40 breaks the test, as intended. +const int buffer_size = 8192; +//const int buffer_size = 40; + +const char name_01[] = "filebuf_virtuals-1.txt"; // file with data in it +const char name_02[] = "filebuf_virtuals-2.txt"; // empty file, need to create +const char name_03[] = "filebuf_virtuals-3.txt"; // empty file, need to create + +class derived_filebuf: public std::filebuf +{ + public: + void + set_size(int_type __size) { _M_buf_size = __size; } +}; + +derived_filebuf fb_01; // in +derived_filebuf fb_02; // out +derived_filebuf fb_03; // in | out + +// Initialize filebufs to be the same size regardless of platform. +void test03() +{ + fb_01.set_size(buffer_size); + fb_02.set_size(buffer_size); + fb_03.set_size(buffer_size); +} + +// Test overloaded virtual functions. +void test05() +{ + typedef std::filebuf::int_type int_type; + typedef std::filebuf::traits_type traits_type; + typedef std::filebuf::pos_type pos_type; + typedef std::filebuf::off_type off_type; + typedef size_t size_type; + + bool test = true; + std::filebuf f_tmp; + std::streamsize strmsz_1, strmsz_2; + std::streamoff strmof_1, strmof_2; + int i = 0, j = 0, k = 0; + + // Unbuffered + fb_01.pubsetbuf(0, 0); + fb_02.pubsetbuf(0, 0); + fb_03.pubsetbuf(0, 0); + + fb_01.open(name_01, std::ios_base::in); + fb_02.open(name_02, std::ios_base::out | std::ios_base::trunc); + fb_03.open(name_03, std::ios_base::out | std::ios_base::in | std::ios_base::trunc); + + int_type c1 = fb_01.sbumpc(); + int_type c2 = fb_02.sbumpc(); + int_type c3 = fb_01.sbumpc(); + int_type c4 = fb_02.sbumpc(); + int_type c5 = fb_03.sbumpc(); + int_type c6 = fb_01.sgetc(); + int_type c7 = fb_02.sgetc(); + int_type c8 = fb_01.sgetc(); + int_type c9 = fb_02.sgetc(); + + // PUT + // int_type sputc(char_type c) + // if out_cur not avail, return overflow(traits_type::to_int_type(c)) + // else, stores c at out_cur, + // increments out_cur, and returns c as int_type + // strmsz_1 = fb_03.in_avail(); // XXX valid for in|out?? + c1 = fb_02.sputc('a'); + c2 = fb_03.sputc('b'); + VERIFY( c1 != c2 ); + c1 = fb_02.sputc('c'); + c2 = fb_03.sputc('d'); + VERIFY( c1 != c2 ); + // strmsz_2 = fb_03.in_avail(); + // VERIFY( strmsz_1 != strmsz_2 ); + for (int i = 50; i <= 90; ++i) + c2 = fb_02.sputc(char(i)); + // 27filebuf-2.txt == ac23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX + // fb_02._M_out_cur = '2' + strmsz_1 = fb_03.in_avail(); + for (int i = 50; i <= 90; ++i) + c2 = fb_03.sputc(char(i)); + strmsz_2 = fb_03.in_avail(); + // VERIFY( strmsz_1 != strmsz_2 ); + // VERIFY( strmsz_1 > 0 ); + // VERIFY( strmsz_2 > 0 ); + // 27filebuf-2.txt == bd23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX + // fb_02._M_out_cur = '2' + c3 = fb_01.sputc('a'); // should be EOF because this is read-only + VERIFY( c3 == traits_type::eof() ); +} + +main() +{ + test03(); + test05(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sputn/char/9339.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputn/char/9339.cc new file mode 100644 index 0000000000000000000000000000000000000000..37a4145044919bc1e8ccd0c4e3a074932e3fa6da --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputn/char/9339.cc @@ -0,0 +1,46 @@ +// Copyright (C) 2003 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 <fstream> +#include <testsuite_hooks.h> + +// libstdc++/9339 +void test01() +{ + using namespace std; + bool test = true; + + filebuf fbuf01; + int len = 35; + fbuf01.pubsetbuf(0, 0); + fbuf01.open("tmp_9339", ios_base::out | ios_base::trunc); + streamsize s1 = fbuf01.sputn("Pete Goldlust @ Carl Hammer Gallery", len); + VERIFY( s1 == len ); + + filebuf fbuf02; + char buf[256]; + fbuf02.open("tmp_9339", ios_base::in); + streamsize s2 = fbuf02.sgetn(buf, 256); + VERIFY( s2 == len ); +} + +int main() +{ + test01(); + return 0; +}