mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-04 17:24:15 +08:00
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:
parent
b16caf72c7
commit
10d9600d58
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user