re PR libstdc++/9761 (filebuf::pbackfail discards previously put back characters)

2003-06-02  Paolo Carlini  <pcarlini@unitus.it>

	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
This commit is contained in:
Paolo Carlini 2003-06-02 18:46:28 +02:00 committed by Paolo Carlini
parent f275a768ab
commit b166bded9e
3 changed files with 94 additions and 45 deletions

View File

@ -1,3 +1,12 @@
2003-06-02 Paolo Carlini <pcarlini@unitus.it>
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 <pcarlini@unitus.it>
* testsuite/27_io/basic_stringbuf/seekpos/char/3.cc: Tweak

View File

@ -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;

View File

@ -0,0 +1,55 @@
// 2003-06-02 Paolo Carlini <pcarlini@unitus.it>
// 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>
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;
}