fstream.tcc (_M_underflow): Do not special case the unbuffered case...
authorPaolo Carlini <pcarlini@unitus.it>
Tue, 10 Jun 2003 00:05:49 +0000 (02:05 +0200)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 10 Jun 2003 00:05:49 +0000 (00:05 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/include/bits/streambuf.tcc
libstdc++-v3/include/std/std_fstream.h
libstdc++-v3/include/std/std_streambuf.h
libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-in.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-io.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-in.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-io.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc [new file with mode: 0644]

index 4cd34f6..1e370c0 100644 (file)
@@ -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.
index a46b478..d988309 100644 (file)
@@ -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
index 502645d..5b76c40 100644 (file)
@@ -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();
index 77350d0..fe72e9d 100644 (file)
@@ -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;
       }
     };
 
index c4159cc..b39ff92 100644 (file)
@@ -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 (file)
index 0000000..bd6e205
--- /dev/null
@@ -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 (file)
index 0000000..fd1708e
--- /dev/null
@@ -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 (file)
index 0000000..78d3b79
--- /dev/null
@@ -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 (file)
index 0000000..5deafbc
--- /dev/null
@@ -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 (file)
index 0000000..fba4481
--- /dev/null
@@ -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 (file)
index 0000000..52f041d
--- /dev/null
@@ -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;
+}