re PR libstdc++/26250 (stringbuf::overflow() fails to set egptr() same as epptr())

2006-02-17  Paolo Carlini  <pcarlini@suse.de>
	    Howard Hinnant  <hhinnant@apple.com>

	PR libstdc++/26250
	* include/bits/sstream.tcc (basic_stringbuf<>::overflow): Tweak
	to leave epgtr() just past the new write position, as per the
	relevant bits of 27.7.1.3/8 (not changed by DR 432).
	* testsuite/27_io/basic_stringbuf/overflow/char/26250.cc: New.
	* testsuite/27_io/basic_stringbuf/overflow/wchar_t/26250.cc: Same.

	* docs/html/ext/howto.html: Add entries for DR 169 and DR 432.

	* include/std/std_sstream.h (basic_stringbuf<>::_M_sync): Move out
	of line...
	* include/bits/sstream.tcc: ... here.

Co-Authored-By: Howard Hinnant <hhinnant@apple.com>

From-SVN: r111177
This commit is contained in:
Paolo Carlini 2006-02-17 10:46:57 +00:00 committed by Paolo Carlini
parent b16caf72c7
commit 10d9600d58
6 changed files with 196 additions and 38 deletions

View File

@ -1,3 +1,19 @@
2006-02-17 Paolo Carlini <pcarlini@suse.de>
Howard Hinnant <hhinnant@apple.com>
PR libstdc++/26250
* include/bits/sstream.tcc (basic_stringbuf<>::overflow): Tweak
to leave epgtr() just past the new write position, as per the
relevant bits of 27.7.1.3/8 (not changed by DR 432).
* testsuite/27_io/basic_stringbuf/overflow/char/26250.cc: New.
* testsuite/27_io/basic_stringbuf/overflow/wchar_t/26250.cc: Same.
* docs/html/ext/howto.html: Add entries for DR 169 and DR 432.
* include/std/std_sstream.h (basic_stringbuf<>::_M_sync): Move out
of line...
* include/bits/sstream.tcc: ... here.
2006-02-16 Joseph S. Myers <joseph@codesourcery.com>
PR libstdc++/14939

View File

@ -358,6 +358,12 @@
calculating an incorrect number of characters to write.
</dd>
<dt><a href="lwg-defects.html#169">169</a>:
<em>Bad efficiency of overflow() mandated</em>
</dt>
<dd>Grow efficiently the internal array object.
</dd>
<dt><a href="lwg-defects.html#171">171</a>:
<em>Strange seekpos() semantics due to joint position</em>
</dt>
@ -536,6 +542,13 @@
<dd>Implement Option 3, as per N1599.
</dd>
<dt><a href="lwg-defects.html#432">432</a>:
<em>432. stringbuf::overflow() makes only one write position
available</em>
</dt>
<dd>Implement the resolution, beyond DR 169.
</dd>
<dt><a href="lwg-defects.html#434">434</a>:
<em>bitset::to_string() hard to use</em>
</dt>

View File

@ -1,6 +1,6 @@
// String based streams -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@ -101,14 +101,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// Try to append __c into output sequence in one of two ways.
// Order these tests done in is unspecified by the standard.
const char_type __conv = traits_type::to_char_type(__c);
if (!__testput)
{
// NB: Start ostringstream buffers at 512 chars. This is an
// NB: Start ostringstream buffers at 512 chars. This is an
// experimental value (pronounced "arbitrary" in some of the
// hipper english-speaking countries), and can be changed to
// suit particular needs.
// Then, in virtue of DR 169 (TC) we are allowed to grow more
// than one char.
//
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 169. Bad efficiency of overflow() mandated
// 432. stringbuf::overflow() makes only one write position
// available
const __size_type __opt_len = std::max(__size_type(2 * __capacity),
__size_type(512));
const __size_type __len = std::min(__opt_len, __max_size);
@ -116,11 +120,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__tmp.reserve(__len);
if (this->pbase())
__tmp.assign(this->pbase(), this->epptr() - this->pbase());
__tmp.push_back(__conv);
_M_string.swap(__tmp);
_M_sync(const_cast<char_type*>(_M_string.data()),
this->gptr() - this->eback(), this->pptr() - this->pbase());
}
return this->sputc(traits_type::to_char_type(__c));
else
*this->pptr() = __conv;
this->pbump(1);
return __c;
}
template <class _CharT, class _Traits, class _Alloc>
@ -203,8 +211,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_update_egptr();
const off_type __pos(__sp);
const bool __testpos = 0 <= __pos
&& __pos <= this->egptr() - __beg;
const bool __testpos = (0 <= __pos
&& __pos <= this->egptr() - __beg);
if (__testpos)
{
if (__testin)
@ -217,6 +225,38 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
return __ret;
}
// Assumes: contents of _M_string and internal buffer match exactly.
// __i == _M_in_cur - _M_in_beg
// __o == _M_out_cur - _M_out_beg
template <class _CharT, class _Traits, class _Alloc>
void
basic_stringbuf<_CharT, _Traits, _Alloc>::
_M_sync(char_type* __base, __size_type __i, __size_type __o)
{
const bool __testin = _M_mode & ios_base::in;
const bool __testout = _M_mode & ios_base::out;
char_type* __end = __base + _M_string.size();
if (__testin)
this->setg(__base, __base + __i, __end);
if (__testout)
{
// If __base comes from setbuf we cannot trust capacity()
// to match the size of the buffer area: in general, after
// Step 1 in setbuf, _M_string.capacity() >= __n.
if (__base == _M_string.data())
this->setp(__base, __base + _M_string.capacity());
else
this->setp(__base, __end);
this->pbump(__o);
// egptr() always tracks the string end. When !__testin,
// for the correct functioning of the streambuf inlines
// the other get area pointers are identical.
if (!__testin)
this->setg(__end, __end, __end);
}
}
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.

View File

@ -1,6 +1,6 @@
// String based streams -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004, 2005
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@ -228,37 +228,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
ios_base::openmode __mode = ios_base::in | ios_base::out);
// Internal function for correctly updating the internal buffer
// for a particular _M_string, due to initialization or
// re-sizing of an existing _M_string.
// Assumes: contents of _M_string and internal buffer match exactly.
// __i == _M_in_cur - _M_in_beg
// __o == _M_out_cur - _M_out_beg
// for a particular _M_string, due to initialization or re-sizing
// of an existing _M_string.
void
_M_sync(char_type* __base, __size_type __i, __size_type __o)
{
const bool __testin = _M_mode & ios_base::in;
const bool __testout = _M_mode & ios_base::out;
char_type* __end = __base + _M_string.size();
if (__testin)
this->setg(__base, __base + __i, __end);
if (__testout)
{
// If __base comes from setbuf we cannot trust capacity()
// to match the size of the buffer area: in general, after
// Step 1 above, _M_string.capacity() >= __n.
if (__base == _M_string.data())
this->setp(__base, __base + _M_string.capacity());
else
this->setp(__base, __end);
this->pbump(__o);
// egptr() always tracks the string end. When !__testin,
// for the correct functioning of the streambuf inlines
// the other get area pointers are identical.
if (!__testin)
this->setg(__end, __end, __end);
}
}
_M_sync(char_type* __base, __size_type __i, __size_type __o);
// Internal function for correctly updating egptr() to the actual
// string end.

View File

@ -0,0 +1,58 @@
// Copyright (C) 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 27.8.1.4 Overridden virtual functions
#include <sstream>
#include <testsuite_hooks.h>
struct pubbuf
: std::stringbuf
{
using std::stringbuf::eback;
using std::stringbuf::egptr;
using std::stringbuf::pbase;
using std::stringbuf::pptr;
using std::stringbuf::epptr;
using std::stringbuf::overflow;
};
// libstdc++/26250
void test01()
{
bool test __attribute__((unused)) = true;
pubbuf buf;
VERIFY( buf.overflow('x') == 'x' );
VERIFY( buf.pptr() - buf.pbase() == 1 );
// not required but good for efficiency
// NB: we are implementing DR 169 and DR 432
const int write_positions = buf.epptr() - buf.pbase();
VERIFY( write_positions > 1 );
// 27.7.1.3, p8:
VERIFY( buf.egptr() - buf.eback() == 1 );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,58 @@
// Copyright (C) 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 27.8.1.4 Overridden virtual functions
#include <sstream>
#include <testsuite_hooks.h>
struct pubbuf
: std::wstringbuf
{
using std::wstringbuf::eback;
using std::wstringbuf::egptr;
using std::wstringbuf::pbase;
using std::wstringbuf::pptr;
using std::wstringbuf::epptr;
using std::wstringbuf::overflow;
};
// libstdc++/26250
void test01()
{
bool test __attribute__((unused)) = true;
pubbuf buf;
VERIFY( buf.overflow(L'x') == L'x' );
VERIFY( buf.pptr() - buf.pbase() == 1 );
// not required but good for efficiency
// NB: we are implementing DR 169 and DR 432
const int write_positions = buf.epptr() - buf.pbase();
VERIFY( write_positions > 1 );
// 27.7.1.3, p8:
VERIFY( buf.egptr() - buf.eback() == 1 );
}
int main()
{
test01();
return 0;
}