From: Paolo Carlini Date: Mon, 2 Jun 2003 16:46:28 +0000 (+0200) Subject: re PR libstdc++/9761 (filebuf::pbackfail discards previously put back characters) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b166bded9e890d88f88ea7b42a78d82b68efb8ac;p=gcc.git re PR libstdc++/9761 (filebuf::pbackfail discards previously put back characters) 2003-06-02 Paolo Carlini PR libstdc++/9761 * include/bits/fstream.tcc (pbackfail): If the pback buffer is already active don't try to store in it a second char. * testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc: New. * include/bits/fstream.tcc (pbackfail): Add unbuffered bits. From-SVN: r67337 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 60347aa9acd..cac15bbc5e0 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2003-06-02 Paolo Carlini + + PR libstdc++/9761 + * include/bits/fstream.tcc (pbackfail): If the pback buffer + is already active don't try to store in it a second char. + * testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc: New. + + * include/bits/fstream.tcc (pbackfail): Add unbuffered bits. + 2003-06-02 Paolo Carlini * testsuite/27_io/basic_stringbuf/seekpos/char/3.cc: Tweak diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index b7915793357..e84eee04efd 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -268,54 +268,39 @@ namespace std if (__testin) { - const bool __testpb = this->_M_in_beg < this->_M_in_cur; - char_type __c = traits_type::to_char_type(__i); + // Remember whether the pback buffer is active, otherwise below + // we may try to store in it a second char (libstdc++/9761). + const bool __testpb = this->_M_pback_init; const bool __testeof = traits_type::eq_int_type(__i, __ret); - - if (__testpb) + + int_type __tmp; + if (this->_M_in_beg < this->_M_in_cur) { - const bool __testout = this->_M_mode & ios_base::out; - const bool __testeq = traits_type::eq(__c, this->_M_in_cur[-1]); - - --this->_M_in_cur; - if (__testout) - --this->_M_out_cur; - // Try to put back __c into input sequence in one of three ways. - // Order these tests done in is unspecified by the standard. - if (!__testeof && __testeq) - __ret = __i; - else if (__testeof) - __ret = traits_type::not_eof(__i); - else - { - _M_create_pback(); - *this->_M_in_cur = __c; - __ret = __i; - } + _M_move_in_cur(-1); + __tmp = traits_type::to_int_type(*this->_M_in_cur); + } + // At the beginning of the buffer, need to make a + // putback position available. + // But the seek may fail (f.i., at the beginning of + // a file, see libstdc++/9439) and in that case + // we return traits_type::eof(). + else if (this->seekoff(-1, ios_base::cur) < 0 + || traits_type::eq_int_type(__tmp = this->underflow(), + traits_type::eof())) + return __ret; + + // Try to put back __i into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (!__testeof && traits_type::eq_int_type(__i, __tmp)) + __ret = __i; + else if (__testeof) + __ret = traits_type::not_eof(__i); + else if (!__testpb) + { + _M_create_pback(); + *this->_M_in_cur = traits_type::to_char_type(__i); + __ret = __i; } - else - { - // At the beginning of the buffer, need to make a - // putback position available. - // But the seek may fail (f.i., at the beginning of - // a file, see libstdc++/9439) and in that case - // we return traits_type::eof() - if (this->seekoff(-1, ios_base::cur) >= 0) - { - this->underflow(); - if (!__testeof) - { - if (!traits_type::eq(__c, *this->_M_in_cur)) - { - _M_create_pback(); - *this->_M_in_cur = __c; - } - __ret = __i; - } - else - __ret = traits_type::not_eof(__i); - } - } } _M_last_overflowed = false; return __ret; diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc new file mode 100644 index 00000000000..07e1ddad810 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc @@ -0,0 +1,55 @@ +// 2003-06-02 Paolo Carlini + +// 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 +#include + +const char name_01[] = "filebuf_virtuals-1.txt"; // file with data in it + +// libstdc++/9761 +void test01() +{ + using namespace std; + bool test = true; + + filebuf fbuf; + filebuf::int_type r1, r2; + + fbuf.open(name_01, ios_base::in); + + fbuf.sbumpc(); + fbuf.sbumpc(); + + r1 = fbuf.sputbackc('a'); + r2 = fbuf.sputbackc('b'); + + fbuf.close(); + + VERIFY( r1 != filebuf::traits_type::eof() ); + VERIFY( r2 == filebuf::traits_type::eof() ); +} + +main() +{ + test01(); + return 0; +}