aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/ChangeLog16
-rw-r--r--libstdc++-v3/docs/html/ext/howto.html13
-rw-r--r--libstdc++-v3/include/bits/sstream.tcc54
-rw-r--r--libstdc++-v3/include/std/std_sstream.h35
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/char/26250.cc58
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/wchar_t/26250.cc58
6 files changed, 196 insertions, 38 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index e001cbd..99af081 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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
diff --git a/libstdc++-v3/docs/html/ext/howto.html b/libstdc++-v3/docs/html/ext/howto.html
index 6aaf994..cf87f6c 100644
--- a/libstdc++-v3/docs/html/ext/howto.html
+++ b/libstdc++-v3/docs/html/ext/howto.html
@@ -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>
diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc
index eb12ca4..95d3d46 100644
--- a/libstdc++-v3/include/bits/sstream.tcc
+++ b/libstdc++-v3/include/bits/sstream.tcc
@@ -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.
diff --git a/libstdc++-v3/include/std/std_sstream.h b/libstdc++-v3/include/std/std_sstream.h
index 162c2a6..712bf7b 100644
--- a/libstdc++-v3/include/std/std_sstream.h
+++ b/libstdc++-v3/include/std/std_sstream.h
@@ -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.
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/char/26250.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/char/26250.cc
new file mode 100644
index 0000000..bf7dcde
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/char/26250.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/wchar_t/26250.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/wchar_t/26250.cc
new file mode 100644
index 0000000..c835ea9
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/wchar_t/26250.cc
@@ -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;
+}