aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@unitus.it>2003-06-10 02:05:49 +0200
committerPaolo Carlini <paolo@gcc.gnu.org>2003-06-10 00:05:49 +0000
commitf10eea7baea18ed271bb7a4571bc7fa42a51b9c0 (patch)
tree4796888c4873be33692877192639786c97003001
parent22597a82ee205a8640b812d29d12811b6a8b6e07 (diff)
downloadgcc-f10eea7baea18ed271bb7a4571bc7fa42a51b9c0.zip
gcc-f10eea7baea18ed271bb7a4571bc7fa42a51b9c0.tar.gz
gcc-f10eea7baea18ed271bb7a4571bc7fa42a51b9c0.tar.bz2
fstream.tcc (_M_underflow): Do not special case the unbuffered case...
2003-06-09 Paolo Carlini <pcarlini@unitus.it> * include/bits/fstream.tcc (_M_underflow): Do not special case the unbuffered case, which really means simply a one char get area. (basic_filebuf): Initialize _M_buf_size. (setbuf): Unbuffered means _M_buf_size == 1, since only _M_buf_size - 1 == 0 chars are going to be used for the put area and 1 for the get area. * include/std/std_streambuf.h (_M_buf_size): Move to basic_filebuf. (~basic_streambuf): Tweak. (basic_streambuf): Do not initialize _M_buf_size. * include/std/std_fstream.h (_M_buf_size): Add from basic_streambuf. (~basic_filebuf): Tweak. (_M_set_buffer): Tweak, considering that _M_buf_size == 1 is the unbuffered situation (i.e., put area pointers NULL). * include/bits/streambuf.tcc (sbumpc): Clean up. * testsuite/27_io/basic_filebuf/sputbackc/char/1.cc: Split into... * testsuite/27_io/basic_filebuf/sputbackc/char/1-in.cc: New. * testsuite/27_io/basic_filebuf/sputbackc/char/1-io.cc: New. * testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc: New. * testsuite/27_io/basic_filebuf/sputbackc/char/2-in.cc: New. * testsuite/27_io/basic_filebuf/sputbackc/char/2-io.cc: New. * testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc: New. From-SVN: r67686
-rw-r--r--libstdc++-v3/ChangeLog25
-rw-r--r--libstdc++-v3/include/bits/fstream.tcc144
-rw-r--r--libstdc++-v3/include/bits/streambuf.tcc6
-rw-r--r--libstdc++-v3/include/std/std_fstream.h26
-rw-r--r--libstdc++-v3/include/std/std_streambuf.h14
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-in.cc92
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-io.cc99
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc70
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-in.cc92
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-io.cc98
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc71
11 files changed, 620 insertions, 117 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4cd34f6..1e370c0 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,28 @@
+2003-06-09 Paolo Carlini <pcarlini@unitus.it>
+
+ * include/bits/fstream.tcc (_M_underflow): Do not special
+ case the unbuffered case, which really means simply a one char
+ get area.
+ (basic_filebuf): Initialize _M_buf_size.
+ (setbuf): Unbuffered means _M_buf_size == 1, since only
+ _M_buf_size - 1 == 0 chars are going to be used for the
+ put area and 1 for the get area.
+ * include/std/std_streambuf.h (_M_buf_size): Move to basic_filebuf.
+ (~basic_streambuf): Tweak.
+ (basic_streambuf): Do not initialize _M_buf_size.
+ * include/std/std_fstream.h (_M_buf_size): Add from basic_streambuf.
+ (~basic_filebuf): Tweak.
+ (_M_set_buffer): Tweak, considering that _M_buf_size == 1 is the
+ unbuffered situation (i.e., put area pointers NULL).
+ * include/bits/streambuf.tcc (sbumpc): Clean up.
+ * testsuite/27_io/basic_filebuf/sputbackc/char/1.cc: Split into...
+ * testsuite/27_io/basic_filebuf/sputbackc/char/1-in.cc: New.
+ * testsuite/27_io/basic_filebuf/sputbackc/char/1-io.cc: New.
+ * testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc: New.
+ * testsuite/27_io/basic_filebuf/sputbackc/char/2-in.cc: New.
+ * testsuite/27_io/basic_filebuf/sputbackc/char/2-io.cc: New.
+ * testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc: New.
+
2003-06-09 Phil Edwards <pme@gcc.gnu.org>
* acinclude.m4: Move all AM_CONDITIONAL calls out.
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index a46b478..d988309 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -71,9 +71,9 @@ namespace std
template<typename _CharT, typename _Traits>
basic_filebuf<_CharT, _Traits>::
basic_filebuf() : __streambuf_type(), _M_file(&_M_lock),
- _M_state_cur(__state_type()), _M_state_beg(__state_type()), _M_buf(NULL),
- _M_buf_allocated(false),_M_last_overflowed(false),
- _M_filepos(0), _M_pback(char_type()), _M_pback_cur_save(0),
+ _M_state_cur(__state_type()), _M_state_beg(__state_type()),
+ _M_buf(NULL), _M_buf_size(BUFSIZ), _M_buf_allocated(false),
+ _M_last_overflowed(false), _M_filepos(0), _M_pback_cur_save(0),
_M_pback_end_save(0), _M_pback_init(false), _M_codecvt(0)
{
this->_M_buf_unified = true;
@@ -193,102 +193,64 @@ namespace std
// fileops happen...
_M_destroy_pback();
- const size_t __buflen = this->_M_buf_size
- ? this->_M_buf_size - 1 : 0;
- if (__buflen)
- {
- if (this->_M_in_cur < this->_M_in_end)
- {
- __ret = traits_type::to_int_type(*this->_M_in_cur);
- if (__bump)
- _M_move_in_cur(1);
- return __ret;
- }
+ const size_t __buflen = this->_M_buf_size > 1
+ ? this->_M_buf_size - 1 : 1;
- // Sync internal and external buffers.
- if (__testout && this->_M_out_beg < this->_M_out_lim)
- this->overflow();
+ if (this->_M_in_cur < this->_M_in_end)
+ {
+ __ret = traits_type::to_int_type(*this->_M_in_cur);
+ if (__bump)
+ _M_move_in_cur(1);
+ return __ret;
+ }
- // Get and convert input sequence.
- streamsize __elen = 0;
- streamsize __ilen = 0;
- if (__check_facet(_M_codecvt).always_noconv())
+ // Sync internal and external buffers.
+ if (__testout && this->_M_out_beg < this->_M_out_lim)
+ this->overflow();
+
+ // Get and convert input sequence.
+ streamsize __elen = 0;
+ streamsize __ilen = 0;
+ if (__check_facet(_M_codecvt).always_noconv())
+ {
+ __elen = _M_file.xsgetn(reinterpret_cast<char*>(this->_M_in_beg), __buflen);
+ __ilen = __elen;
+ }
+ else
+ {
+ char* __buf = static_cast<char*>(__builtin_alloca(__buflen));
+ __elen = _M_file.xsgetn(__buf, __buflen);
+
+ const char* __eend;
+ char_type* __iend;
+ codecvt_base::result __r;
+ __r = _M_codecvt->in(_M_state_cur, __buf, __buf + __elen,
+ __eend, this->_M_in_beg,
+ this->_M_in_beg + __buflen, __iend);
+ if (__r == codecvt_base::ok)
+ __ilen = __iend - this->_M_in_beg;
+ else if (__r == codecvt_base::noconv)
{
- __elen = _M_file.xsgetn(reinterpret_cast<char*>(this->_M_in_beg), __buflen);
+ traits_type::copy(this->_M_in_beg,
+ reinterpret_cast<char_type*>(__buf),
+ __elen);
__ilen = __elen;
}
- else
+ else
{
- char* __buf = static_cast<char*>(__builtin_alloca(__buflen));
- __elen = _M_file.xsgetn(__buf, __buflen);
-
- const char* __eend;
- char_type* __iend;
- codecvt_base::result __r;
- __r = _M_codecvt->in(_M_state_cur, __buf, __buf + __elen,
- __eend, this->_M_in_beg,
- this->_M_in_beg + __buflen, __iend);
- if (__r == codecvt_base::ok)
- __ilen = __iend - this->_M_in_beg;
- else if (__r == codecvt_base::noconv)
- {
- traits_type::copy(this->_M_in_beg,
- reinterpret_cast<char_type*>(__buf),
- __elen);
- __ilen = __elen;
- }
- else
- {
- // Unwind.
- __ilen = 0;
- _M_file.seekoff(-__elen, ios_base::cur, ios_base::in);
- }
+ // Unwind.
+ __ilen = 0;
+ _M_file.seekoff(-__elen, ios_base::cur, ios_base::in);
}
-
- if (__ilen > 0)
- {
- _M_set_buffer(__ilen);
- __ret = traits_type::to_int_type(*this->_M_in_cur);
- if (__bump)
- _M_move_in_cur(1);
- }
}
- else
+
+ if (__ilen > 0)
{
- // Unbuffered.
- char __buf;
- if (_M_file.xsgetn(&__buf, 1) > 0)
- {
- if (__check_facet(_M_codecvt).always_noconv())
- {
- char_type* __cp = reinterpret_cast<char_type*>(&__buf);
- __ret = traits_type::to_int_type(*__cp);
- }
- else
- {
- char_type __c;
- const char* __eend;
- char_type* __iend;
- codecvt_base::result __r;
- __r = _M_codecvt->in(_M_state_cur, &__buf, &__buf + 1,
- __eend, &__c, &__c + 1, __iend);
- if (__r == codecvt_base::ok
- || __r == codecvt_base::noconv)
- __ret = traits_type::to_int_type(__c);
- }
-
- // Need to put back this extracted character so that
- // sgetc will not advance the input stream iff
- // underflow, but cannot call pbackfail directly as
- // it calls underflow... which leads to a recursive
- // showdown.
- if (!__bump)
- {
- _M_create_pback();
- *this->_M_in_cur = traits_type::to_char_type(__ret);
- }
- }
- }
+ _M_set_buffer(__ilen);
+ __ret = traits_type::to_int_type(*this->_M_in_cur);
+ if (__bump)
+ _M_move_in_cur(1);
+ }
}
_M_last_overflowed = false;
return __ret;
@@ -467,7 +429,7 @@ namespace std
setbuf(char_type* __s, streamsize __n)
{
if (!this->is_open() && __s == 0 && __n == 0)
- this->_M_buf_size = 0;
+ this->_M_buf_size = 1;
else if (__s && __n > 1)
{
// This is implementation-defined behavior, and assumes that
diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc
index 502645d..5b76c40 100644
--- a/libstdc++-v3/include/bits/streambuf.tcc
+++ b/libstdc++-v3/include/bits/streambuf.tcc
@@ -48,12 +48,8 @@ namespace std
if (_M_in_cur < _M_in_end)
{
char_type __c = *this->_M_in_cur;
+ _M_move_in_cur(1);
__ret = traits_type::to_int_type(__c);
-
- if (_M_buf_size)
- _M_move_in_cur(1);
- else
- this->underflow();
}
else
__ret = this->uflow();
diff --git a/libstdc++-v3/include/std/std_fstream.h b/libstdc++-v3/include/std/std_fstream.h
index 77350d0..fe72e9d 100644
--- a/libstdc++-v3/include/std/std_fstream.h
+++ b/libstdc++-v3/include/std/std_fstream.h
@@ -121,6 +121,15 @@ namespace std
*/
char_type* _M_buf;
+ /**
+ * @if maint
+ * Actual size of internal buffer. This number is equal to the size
+ * of the put area + 1 position, reserved for the overflow char of
+ * a full area.
+ * @endif
+ */
+ size_t _M_buf_size;
+
// Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
/**
* @if maint
@@ -206,6 +215,7 @@ namespace std
~basic_filebuf()
{
this->close();
+ _M_buf_size = 0;
_M_last_overflowed = false;
}
@@ -429,17 +439,15 @@ namespace std
{
const bool __testin = this->_M_mode & ios_base::in;
const bool __testout = this->_M_mode & ios_base::out;
- if (this->_M_buf_size)
+
+ if (__testin)
+ this->setg(this->_M_buf, this->_M_buf, this->_M_buf + __off);
+ if (__testout && this->_M_buf_size > 1)
{
- if (__testin)
- this->setg(this->_M_buf, this->_M_buf, this->_M_buf + __off);
- if (__testout)
- {
- this->setp(this->_M_buf, this->_M_buf + this->_M_buf_size - 1);
- this->_M_out_lim += __off;
- }
- _M_filepos = this->_M_buf + __off;
+ this->setp(this->_M_buf, this->_M_buf + this->_M_buf_size - 1);
+ this->_M_out_lim += __off;
}
+ _M_filepos = this->_M_buf + __off;
}
};
diff --git a/libstdc++-v3/include/std/std_streambuf.h b/libstdc++-v3/include/std/std_streambuf.h
index c4159cc..b39ff92 100644
--- a/libstdc++-v3/include/std/std_streambuf.h
+++ b/libstdc++-v3/include/std/std_streambuf.h
@@ -197,15 +197,6 @@ namespace std
/**
* @if maint
- * Actual size of internal buffer. This number is equal to the size
- * of the put area + 1 position, reserved for the overflow char of
- * a full area.
- * @endif
- */
- size_t _M_buf_size;
-
- /**
- * @if maint
* Place to stash in || out || in | out settings for current streambuf.
* @endif
*/
@@ -267,7 +258,6 @@ namespace std
~basic_streambuf()
{
_M_buf_unified = false;
- _M_buf_size = 0;
_M_mode = ios_base::openmode(0);
}
@@ -468,8 +458,8 @@ namespace std
*/
basic_streambuf()
: _M_in_beg(0), _M_in_cur(0), _M_in_end(0),
- _M_out_beg(0), _M_out_cur(0), _M_out_end(0),_M_out_lim(0),
- _M_buf_unified(false), _M_buf_size(BUFSIZ),
+ _M_out_beg(0), _M_out_cur(0), _M_out_end(0),
+ _M_out_lim(0), _M_buf_unified(false),
_M_mode(ios_base::openmode(0)),_M_buf_locale(locale())
{ }
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-in.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-in.cc
new file mode 100644
index 0000000..bd6e205
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-in.cc
@@ -0,0 +1,92 @@
+// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001, 2002, 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>
+#include <testsuite_io.h>
+
+// @require@ %-*.tst %-*.txt
+// @diff@ %-*.tst %*.txt
+
+const char name_01[] = "sgetc.txt"; // file with data in it
+
+// Test overloaded virtual functions.
+void test01()
+{
+ using namespace std;
+ using namespace __gnu_cxx_test;
+ typedef std::filebuf::int_type int_type;
+ typedef filebuf::traits_type traits_type;
+
+ bool test = true;
+ int_type c1, c2, c3;
+
+ // int_type sputbackc(char_type c)
+ // if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
+ // otherwise decrements in_cur and returns *gptr()
+
+ // in
+ {
+ constraint_filebuf fb_01; // in
+ fb_01.open(name_01, ios::in);
+ VERIFY( !fb_01.write_position() );
+ c1 = fb_01.sbumpc();
+ VERIFY( c1 == '/' );
+ c2 = fb_01.sputbackc('/');
+ VERIFY( c1 == c2 );
+ c3 = fb_01.sgetc();
+ VERIFY( c3 == c2 );
+ c3 = fb_01.sbumpc();
+ VERIFY( c3 == c2 );
+ fb_01.sbumpc();
+ c3 = fb_01.sbumpc();
+ VERIFY( c3 == ' ' );
+ c1 = fb_01.sgetc();
+ c2 = fb_01.sputbackc('a');
+ VERIFY( c2 == 'a' );
+ c3 = fb_01.sbumpc();
+ VERIFY( c3 == c2 );
+ c3 = fb_01.sgetc();
+ VERIFY( c1 == c3 );
+ fb_01.pubseekoff(5, ios_base::beg, ios_base::in);
+ c1 = fb_01.sgetc();
+ VERIFY( c1 == '0' );
+ fb_01.sbumpc();
+ c1 = fb_01.sbumpc();
+ VERIFY( c1 == '1' );
+ c2 = fb_01.sputbackc('b');
+ VERIFY( c2 == 'b' );
+ fb_01.sbumpc();
+ c3 = fb_01.sbumpc();
+ VERIFY( c3 == '1' );
+ c3 = fb_01.sbumpc();
+ VERIFY( c3 == '7' );
+ VERIFY( !fb_01.write_position() );
+ VERIFY( fb_01.read_position() );
+ }
+}
+
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-io.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-io.cc
new file mode 100644
index 0000000..fd1708e
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-io.cc
@@ -0,0 +1,99 @@
+// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001, 2002, 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>
+#include <testsuite_io.h>
+
+// @require@ %-*.tst %-*.txt
+// @diff@ %-*.tst %*.txt
+
+const char name_01[] = "tmp_sputbackc_1io.tst"; // empty file, need to create
+
+void test01()
+{
+ using namespace std;
+ using namespace __gnu_cxx_test;
+
+ typedef filebuf::int_type int_type;
+ typedef filebuf::traits_type traits_type;
+ typedef size_t size_type;
+
+ bool test = true;
+ streamsize strmsz_1, strmsz_2;
+ int_type c1, c2, c3;
+
+ // int_type sputbackc(char_type c)
+ // if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
+ // otherwise decrements in_cur and returns *gptr()
+
+ // in | out
+ {
+ constraint_filebuf fb_01;
+ fb_01.open(name_01, ios_base::out | ios_base::in | ios_base::trunc);
+ VERIFY( fb_01.write_position() );
+ VERIFY( !fb_01.read_position() );
+ strmsz_1 = fb_01.sputn("racadabras", 10);//"abracadabras or what?"
+ strmsz_2 = fb_01.sputn(", i wanna reach out and", 10);
+ c1 = fb_01.sgetc(); // -1
+ c2 = fb_01.sputbackc('z');
+ strmsz_2 = fb_01.in_avail();
+ c3 = fb_01.sgetc();
+ VERIFY( c3 == c2 );
+ VERIFY( c1 != c3 );
+ VERIFY( 1 == strmsz_2 );
+ //test for _in_cur == _in_beg
+ // fb_01._M_out_beg = "bd23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZracada" etc
+ fb_01.pubseekoff(10, std::ios_base::beg,
+ std::ios_base::in | std::ios_base::out);
+ fb_01.sputc('m');
+ strmsz_1 = fb_01.in_avail();
+ c1 = fb_01.sgetc();
+ fb_01.snextc();
+ c2 = fb_01.sputbackc('z');
+ strmsz_2 = fb_01.in_avail();
+ c3 = fb_01.sgetc();
+ VERIFY( c1 != c2 );
+ VERIFY( c3 == c2 );
+ VERIFY( c1 != c3 );
+ VERIFY( c2 == 'z' );
+ // test for replacing char with identical one
+ fb_01.snextc();
+ fb_01.sputc('u');
+ fb_01.sputc('v');
+ fb_01.sputc('a');
+ strmsz_1 = fb_01.in_avail();
+ c2 = fb_01.sputbackc('a');
+ strmsz_2 = fb_01.in_avail();
+ c3 = fb_01.sgetc();
+ VERIFY( c3 == c2 );
+ VERIFY( strmsz_1 + 1 == strmsz_2 );
+ VERIFY( fb_01.write_position() );
+ VERIFY( fb_01.read_position() );
+ }
+}
+
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc
new file mode 100644
index 0000000..78d3b79
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc
@@ -0,0 +1,70 @@
+// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001, 2002, 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>
+#include <testsuite_io.h>
+
+// @require@ %-*.tst %-*.txt
+// @diff@ %-*.tst %*.txt
+
+const char name_01[] = "tmp_sputbackc_1out.tst"; // empty file, need to create
+
+// Test overloaded virtual functions.
+void test01()
+{
+ using namespace std;
+ using namespace __gnu_cxx_test;
+ typedef std::filebuf::int_type int_type;
+ typedef filebuf::traits_type traits_type;
+
+ bool test = true;
+ int_type c1, c2, c3;
+
+ // int_type sputbackc(char_type c)
+ // if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
+ // otherwise decrements in_cur and returns *gptr()
+
+ // out
+ {
+ constraint_filebuf fb_01; // out
+ fb_01.open(name_01, ios::out | ios::trunc);
+ VERIFY( fb_01.write_position() );
+ VERIFY( !fb_01.read_position() );
+ c1 = fb_01.sgetc();
+ VERIFY( c1 == traits_type::eof() );
+ c2 = fb_01.sputbackc('a');
+ VERIFY( c2 == traits_type::eof() );
+ fb_01.sbumpc();
+ c1 = fb_01.sbumpc();
+ c2 = fb_01.sputbackc('a');
+ VERIFY( c1 == c2 );
+ VERIFY( fb_01.write_position() );
+ VERIFY( !fb_01.read_position() );
+ }
+}
+
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-in.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-in.cc
new file mode 100644
index 0000000..5deafbc
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-in.cc
@@ -0,0 +1,92 @@
+// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001, 2002, 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>
+#include <testsuite_io.h>
+
+// @require@ %-*.tst %-*.txt
+// @diff@ %-*.tst %*.txt
+
+const char name_01[] = "sgetc.txt"; // file with data in it
+
+// Test overloaded virtual functions.
+void test01()
+{
+ using namespace std;
+ using namespace __gnu_cxx_test;
+ typedef std::filebuf::int_type int_type;
+ typedef filebuf::traits_type traits_type;
+
+ bool test = true;
+ int_type c1, c2, c3;
+
+ // int_type sputbackc(char_type c)
+ // if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
+ // otherwise decrements in_cur and returns *gptr()
+
+ // in
+ {
+ constraint_filebuf fb_01; // in
+ fb_01.pubsetbuf(0, 0);
+ fb_01.open(name_01, ios::in);
+ VERIFY( fb_01.unbuffered() );
+ c1 = fb_01.sbumpc();
+ VERIFY( c1 == '/' );
+ c2 = fb_01.sputbackc('/');
+ VERIFY( c1 == c2 );
+ c3 = fb_01.sgetc();
+ VERIFY( c3 == c2 );
+ c3 = fb_01.sbumpc();
+ VERIFY( c3 == c2 );
+ fb_01.sbumpc();
+ c3 = fb_01.sbumpc();
+ VERIFY( c3 == ' ' );
+ c1 = fb_01.sgetc();
+ c2 = fb_01.sputbackc('a');
+ VERIFY( c2 == 'a' );
+ c3 = fb_01.sbumpc();
+ VERIFY( c3 == c2 );
+ c3 = fb_01.sgetc();
+ VERIFY( c1 == c3 );
+ fb_01.pubseekoff(5, ios_base::beg, ios_base::in);
+ c1 = fb_01.sgetc();
+ VERIFY( c1 == '0' );
+ fb_01.sbumpc();
+ c1 = fb_01.sbumpc();
+ VERIFY( c1 == '1' );
+ c2 = fb_01.sputbackc('b');
+ VERIFY( c2 == 'b' );
+ fb_01.sbumpc();
+ c3 = fb_01.sbumpc();
+ VERIFY( c3 == '1' );
+ c3 = fb_01.sbumpc();
+ VERIFY( c3 == '7' );
+ VERIFY( fb_01.unbuffered() );
+ }
+}
+
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-io.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-io.cc
new file mode 100644
index 0000000..fba4481
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-io.cc
@@ -0,0 +1,98 @@
+// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001, 2002, 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>
+#include <testsuite_io.h>
+
+// @require@ %-*.tst %-*.txt
+// @diff@ %-*.tst %*.txt
+
+const char name_01[] = "tmp_sputbackc_2io.tst"; // empty file, need to create
+
+void test01()
+{
+ using namespace std;
+ using namespace __gnu_cxx_test;
+
+ typedef filebuf::int_type int_type;
+ typedef filebuf::traits_type traits_type;
+ typedef size_t size_type;
+
+ bool test = true;
+ streamsize strmsz_1, strmsz_2;
+ int_type c1, c2, c3;
+
+ // int_type sputbackc(char_type c)
+ // if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
+ // otherwise decrements in_cur and returns *gptr()
+
+ // in | out
+ {
+ constraint_filebuf fb_01;
+ fb_01.pubsetbuf(0, 0);
+ fb_01.open(name_01, ios_base::out | ios_base::in | ios_base::trunc);
+ VERIFY( fb_01.unbuffered() );
+ strmsz_1 = fb_01.sputn("racadabras", 10);//"abracadabras or what?"
+ strmsz_2 = fb_01.sputn(", i wanna reach out and", 10);
+ c1 = fb_01.sgetc(); // -1
+ c2 = fb_01.sputbackc('z');
+ strmsz_2 = fb_01.in_avail();
+ c3 = fb_01.sgetc();
+ VERIFY( c3 == c2 );
+ VERIFY( c1 != c3 );
+ VERIFY( 1 == strmsz_2 );
+ //test for _in_cur == _in_beg
+ // fb_01._M_out_beg = "bd23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZracada" etc
+ fb_01.pubseekoff(10, std::ios_base::beg,
+ std::ios_base::in | std::ios_base::out);
+ fb_01.sputc('m');
+ strmsz_1 = fb_01.in_avail();
+ c1 = fb_01.sgetc();
+ fb_01.snextc();
+ c2 = fb_01.sputbackc('z');
+ strmsz_2 = fb_01.in_avail();
+ c3 = fb_01.sgetc();
+ VERIFY( c1 != c2 );
+ VERIFY( c3 == c2 );
+ VERIFY( c1 != c3 );
+ VERIFY( c2 == 'z' );
+ // test for replacing char with identical one
+ fb_01.snextc();
+ fb_01.sputc('u');
+ fb_01.sputc('v');
+ fb_01.sputc('a');
+ strmsz_1 = fb_01.in_avail();
+ c2 = fb_01.sputbackc('a');
+ strmsz_2 = fb_01.in_avail();
+ c3 = fb_01.sgetc();
+ VERIFY( c3 == c2 );
+ VERIFY( strmsz_1 == strmsz_2 );
+ VERIFY( fb_01.unbuffered() );
+ }
+}
+
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc
new file mode 100644
index 0000000..52f041d
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc
@@ -0,0 +1,71 @@
+// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001, 2002, 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>
+#include <testsuite_io.h>
+
+// @require@ %-*.tst %-*.txt
+// @diff@ %-*.tst %*.txt
+
+const char name_01[] = "tmp_sputbackc_2out.tst"; // empty file, need to create
+
+// Test overloaded virtual functions.
+void test01()
+{
+ using namespace std;
+ using namespace __gnu_cxx_test;
+ typedef std::filebuf::int_type int_type;
+ typedef filebuf::traits_type traits_type;
+
+ bool test = true;
+ int_type c1, c2, c3;
+
+ // int_type sputbackc(char_type c)
+ // if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
+ // otherwise decrements in_cur and returns *gptr()
+
+ // out
+ {
+ constraint_filebuf fb_01; // out
+ fb_01.pubsetbuf(0, 0);
+ fb_01.open(name_01, ios::out | ios::trunc);
+ VERIFY( fb_01.unbuffered() );
+ VERIFY( !fb_01.read_position() );
+ c1 = fb_01.sgetc();
+ VERIFY( c1 == traits_type::eof() );
+ c2 = fb_01.sputbackc('a');
+ VERIFY( c2 == traits_type::eof() );
+ fb_01.sbumpc();
+ c1 = fb_01.sbumpc();
+ c2 = fb_01.sputbackc('a');
+ VERIFY( c1 == c2 );
+ VERIFY( fb_01.unbuffered() );
+ VERIFY( !fb_01.read_position() );
+ }
+}
+
+main()
+{
+ test01();
+ return 0;
+}