OSDN Git Service

2003-06-02 Paolo Carlini <pcarlini@unitus.it>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 2 Jun 2003 16:46:28 +0000 (16:46 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 2 Jun 2003 16:46:28 +0000 (16:46 +0000)
PR libstdc++/9761
* include/bits/fstream.tcc (pbackfail): If the pback buffer
is already active don't try to store in it a second char.
* testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc: New.

* include/bits/fstream.tcc (pbackfail): Add unbuffered bits.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@67337 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc [new file with mode: 0644]

index 60347aa..cac15bb 100644 (file)
@@ -1,5 +1,14 @@
 2003-06-02  Paolo Carlini  <pcarlini@unitus.it>
 
+       PR libstdc++/9761
+       * include/bits/fstream.tcc (pbackfail): If the pback buffer
+       is already active don't try to store in it a second char.
+       * testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc: New.
+
+       * include/bits/fstream.tcc (pbackfail): Add unbuffered bits.
+
+2003-06-02  Paolo Carlini  <pcarlini@unitus.it>
+
        * testsuite/27_io/basic_stringbuf/seekpos/char/3.cc: Tweak
        line spacing.
 
index b791579..e84eee0 100644 (file)
@@ -268,54 +268,39 @@ namespace std
 
       if (__testin)
        {
-         const bool __testpb = this->_M_in_beg < this->_M_in_cur;
-         char_type __c = traits_type::to_char_type(__i);
+         // Remember whether the pback buffer is active, otherwise below
+         // we may try to store in it a second char (libstdc++/9761).
+         const bool __testpb = this->_M_pback_init;       
          const bool __testeof = traits_type::eq_int_type(__i, __ret);
-
-         if (__testpb)
+         
+         int_type __tmp;
+         if (this->_M_in_beg < this->_M_in_cur)
            {
-             const bool __testout = this->_M_mode & ios_base::out;
-             const bool __testeq = traits_type::eq(__c, this->_M_in_cur[-1]);
-
-             --this->_M_in_cur;
-             if (__testout)
-               --this->_M_out_cur;
-             // Try to put back __c into input sequence in one of three ways.
-             // Order these tests done in is unspecified by the standard.
-             if (!__testeof && __testeq)
-               __ret = __i;
-             else if (__testeof)
-               __ret = traits_type::not_eof(__i);
-             else
-               {
-                 _M_create_pback();
-                 *this->_M_in_cur = __c; 
-                 __ret = __i;
-               }
+             _M_move_in_cur(-1);
+             __tmp = traits_type::to_int_type(*this->_M_in_cur);
+           }
+         // At the beginning of the buffer, need to make a
+         // putback position available.
+         // But the seek may fail (f.i., at the beginning of
+         // a file, see libstdc++/9439) and in that case
+         // we return traits_type::eof().
+         else if (this->seekoff(-1, ios_base::cur) < 0
+                  || traits_type::eq_int_type(__tmp = this->underflow(),
+                                              traits_type::eof()))
+           return __ret;
+
+         // Try to put back __i into input sequence in one of three ways.
+         // Order these tests done in is unspecified by the standard.
+         if (!__testeof && traits_type::eq_int_type(__i, __tmp))
+           __ret = __i;
+         else if (__testeof)
+           __ret = traits_type::not_eof(__i);
+         else if (!__testpb)
+           {
+             _M_create_pback();
+             *this->_M_in_cur = traits_type::to_char_type(__i); 
+             __ret = __i;
            }
-         else
-           {    
-             // At the beginning of the buffer, need to make a
-             // putback position available.
-             // But the seek may fail (f.i., at the beginning of
-             // a file, see libstdc++/9439) and in that case
-             // we return traits_type::eof()
-             if (this->seekoff(-1, ios_base::cur) >= 0)
-               {
-                 this->underflow();
-                 if (!__testeof)
-                   {
-                     if (!traits_type::eq(__c, *this->_M_in_cur))
-                       {
-                         _M_create_pback();
-                         *this->_M_in_cur = __c;
-                       }
-                     __ret = __i;
-                   }
-                 else
-                   __ret = traits_type::not_eof(__i);
-               }
-           }
        }
       _M_last_overflowed = false;      
       return __ret;
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc
new file mode 100644 (file)
index 0000000..07e1dda
--- /dev/null
@@ -0,0 +1,55 @@
+// 2003-06-02 Paolo Carlini <pcarlini@unitus.it>
+
+// Copyright (C) 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>
+
+const char name_01[] = "filebuf_virtuals-1.txt"; // file with data in it
+
+// libstdc++/9761
+void test01()
+{
+  using namespace std;
+  bool test = true;
+
+  filebuf fbuf;
+  filebuf::int_type r1, r2;
+
+  fbuf.open(name_01, ios_base::in);
+  
+  fbuf.sbumpc();
+  fbuf.sbumpc();
+       
+  r1 = fbuf.sputbackc('a');
+  r2 = fbuf.sputbackc('b');
+
+  fbuf.close();
+
+  VERIFY( r1 != filebuf::traits_type::eof() );
+  VERIFY( r2 == filebuf::traits_type::eof() );
+}
+
+main() 
+{
+  test01();
+  return 0;
+}