OSDN Git Service

2002-04-08 Benjamin Kosnik <bkoz@redhat.com>
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Apr 2002 06:14:32 +0000 (06:14 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Apr 2002 06:14:32 +0000 (06:14 +0000)
libstdc++/5180
* include/bits/fstream.tcc (filebuf::seekpos): Fix.
* include/std/std_fstream.h: Clean.
* include/bits/ostream.tcc: Remove extraneous variables.
* include/bits/sstream.tcc (stringbuf::seekoff): Be strict about
open modes and which modes.
(stringbuf::seekpos): Same.
* testsuite/27_io/stringbuf_virtuals.cc: New tests.

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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/include/bits/ostream.tcc
libstdc++-v3/include/bits/sstream.tcc
libstdc++-v3/include/std/std_fstream.h
libstdc++-v3/testsuite/27_io/stringbuf_virtuals.cc

index 97de30d..64e40fa 100644 (file)
@@ -1,3 +1,14 @@
+2002-04-08  Benjamin Kosnik  <bkoz@redhat.com>
+
+       libstdc++/5180
+       * include/bits/fstream.tcc (filebuf::seekpos): Fix.
+       * include/std/std_fstream.h: Clean.
+       * include/bits/ostream.tcc: Remove extraneous variables.
+       * include/bits/sstream.tcc (stringbuf::seekoff): Be strict about
+       open modes and which modes.
+       (stringbuf::seekpos): Same.
+       * testsuite/27_io/stringbuf_virtuals.cc: New tests.
+       
 2002-04-05  Jonathan Wakely <jw@kayari.org>
 
        * include/bits/stl_algo.h (unique_copy, __gcd, rotate, rotate_copy,
index 0d08826..0117d57 100644 (file)
@@ -560,17 +560,17 @@ namespace std
     seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
     {
       pos_type __ret =  pos_type(off_type(-1)); 
-      bool __testopen = this->is_open();
-      bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
-      bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
+      bool __testin = _M_mode & ios_base::in;
+      bool __testout = _M_mode & ios_base::out;
 
       // Should probably do has_facet checks here.
       int __width = use_facet<__codecvt_type>(_M_buf_locale).encoding();
       if (__width < 0)
        __width = 0;
-      bool __testfail = __off != 0  && __width <= 0;
+      bool __testfail = __off != 0 && __width <= 0;
       
-      if (__testopen && !__testfail && (__testin || __testout))
+      if (this->is_open() && !__testfail 
+         && __mode & _M_mode && (__testin || __testout))
        {
          // Ditch any pback buffers to avoid confusion.
          _M_pback_destroy();
@@ -615,13 +615,10 @@ namespace std
     basic_filebuf<_CharT, _Traits>::
     seekpos(pos_type __pos, ios_base::openmode __mode)
     {
-      pos_type __ret;
-      off_type __off = __pos;
-
-      __ret = this->seekoff(__off, ios_base::beg, __mode); 
-
-      _M_last_overflowed = false;      
-      return __ret;
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+// 171. Strange seekpos() semantics due to joint position
+      return this->seekoff(off_type(__pos), ios_base::beg, __mode);
+#endif
     }
 
   template<typename _CharT, typename _Traits>
index 785df85..5c4799b 100644 (file)
@@ -419,9 +419,7 @@ namespace std
     basic_ostream<_CharT, _Traits>::tellp()
     {
       pos_type __ret = pos_type(-1);
-      bool __testok = this->fail() != true;
-      
-      if (__testok)
+      if (!this->fail())
        __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
       return __ret;
     }
@@ -431,9 +429,7 @@ namespace std
     basic_ostream<_CharT, _Traits>&
     basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
     {
-      bool __testok = this->fail() != true;
-      
-      if (__testok)
+      if (!this->fail())
        {
 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
 // 136.  seekp, seekg setting wrong streams?
@@ -452,9 +448,7 @@ namespace std
     basic_ostream<_CharT, _Traits>::
     seekp(off_type __off, ios_base::seekdir __d)
     {
-      bool __testok = this->fail() != true;
-      
-      if (__testok)
+      if (!this->fail())
        {
 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
 // 136.  seekp, seekg setting wrong streams?
index f83bb69..6aec6e8 100644 (file)
@@ -124,8 +124,10 @@ namespace std
       bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
       bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
       bool __testboth = __testin && __testout && __way != ios_base::cur;
-      
-      if (_M_buf_size && ((__testin != __testout) || __testboth))
+      __testin &= !(__mode & ios_base::out);
+      __testout &= !(__mode & ios_base::in);
+
+      if (_M_buf_size && (__testin || __testout || __testboth))
        {
          char_type* __beg = _M_buf;
          char_type* __curi = NULL;
@@ -133,12 +135,12 @@ namespace std
          char_type* __endi = NULL;
          char_type* __endo = NULL;
 
-         if (__testin)
+         if (__testin || __testboth)
            {
              __curi = this->gptr();
              __endi = this->egptr();
            }
-         if (__testout)
+         if (__testout || __testboth)
            {
              __curo = this->pptr();
              __endo = this->epptr();
@@ -157,13 +159,13 @@ namespace std
              __newoffo = __endo - __beg;
            }
 
-         if (__testin
+         if ((__testin || __testboth)
              && __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off)
            {
              _M_in_cur = __beg + __newoffi + __off;
              __ret = pos_type(__newoffi);
            }
-         if (__testout
+         if ((__testout || __testboth)
              && __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off)
            {
              _M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg));
@@ -179,33 +181,44 @@ namespace std
     seekpos(pos_type __sp, ios_base::openmode __mode)
     {
       pos_type __ret =  pos_type(off_type(-1)); 
-      off_type __pos = __sp._M_position();
-      char_type* __beg = NULL;
-      char_type* __end = NULL;
-      bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
-      bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
       
-      if (__testin)
-       {
-         __beg = this->eback();
-         __end = this->egptr();
-       }
-      if (__testout)
-       {
-         __beg = this->pbase();
-         __end = _M_buf + _M_buf_size;
-       }
-      if (0 <= __pos && __pos <= __end - __beg)
+      if (_M_buf_size)
        {
-         // Need to set both of these if applicable
-         if (__testin)
-           _M_in_cur = _M_in_beg + __pos;
-         if (__testout)
-           _M_out_cur_move((__pos) - (_M_out_cur - __beg));
-         __ret = pos_type(off_type(__pos));
+         off_type __pos = __sp._M_position();
+         char_type* __beg = NULL;
+         char_type* __end = NULL;
+         bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
+         bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
+         bool __testboth = __testin && __testout;
+         __testin &= !(__mode & ios_base::out);
+         __testout &= !(__mode & ios_base::in);
+         
+         // NB: Ordered.
+         bool __testposi = false;
+         bool __testposo = false;
+         if (__testin || __testboth)
+           {
+             __beg = this->eback();
+             __end = this->egptr();
+             if (0 <= __pos && __pos <= __end - __beg)
+               __testposi = true;
+           }
+         if (__testout || __testboth)
+           {
+             __beg = this->pbase();
+             __end = _M_buf + _M_buf_size;
+             if (0 <= __pos && __pos <= __end - __beg)
+               __testposo = true;
+           }
+         if (__testposi || __testposo)
+           {
+             if (__testposi)
+               _M_in_cur = _M_in_beg + __pos;
+             if (__testposo)
+               _M_out_cur_move((__pos) - (_M_out_cur - __beg));
+             __ret = pos_type(off_type(__pos));
+           }
        }
-      
       return __ret;
     }
 
index c3273b5..c462e7b 100644 (file)
@@ -306,7 +306,7 @@ namespace std
       void
       open(const char* __s, ios_base::openmode __mode = ios_base::in)
       {
-       if (_M_filebuf.open(__s, __mode | ios_base::in) == NULL)
+       if (!_M_filebuf.open(__s, __mode | ios_base::in))
          this->setstate(ios_base::failbit);
       }
 
index 7e20164..318bb72 100644 (file)
@@ -1,6 +1,6 @@
 // 2001-05-21 Benjamin Kosnik  <bkoz@redhat.com>
 
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002 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
@@ -38,9 +38,50 @@ void test01()
   VERIFY( std::strncmp(strlit, buf, strlitsize) != 0 );
 }
 
+void test02(std::stringbuf& in, bool pass)
+{
+  using namespace std;
+  typedef streambuf::pos_type pos_type;
+  typedef streambuf::off_type off_type;
+  pos_type bad = pos_type(off_type(-1));
+  pos_type p = 0;
+
+  // seekoff
+  p = in.pubseekoff(0, ios_base::beg, ios_base::in);
+  if (pass)
+    VERIFY( p != bad );
+
+  p = in.pubseekoff(0, ios_base::beg, ios_base::out); 
+  VERIFY( p == bad );
+
+  p = in.pubseekoff(0, ios_base::beg); 
+  VERIFY( p == bad );
+
+
+  // seekpos
+  p = in.pubseekpos(0, ios_base::in);
+  if (pass)
+    VERIFY( p != bad );
+
+  p = in.pubseekpos(0, ios_base::out); 
+  VERIFY( p == bad );
+
+  p = in.pubseekpos(0); 
+  VERIFY( p == bad );
+}
+
 int main() 
 {
+  using namespace std;
   test01();
 
+  // movie star, submarine scientist!
+  stringbuf in1("Hedy Lamarr", ios_base::in);
+  stringbuf in2(ios_base::in);
+  stringbuf in3("", ios_base::in);
+  test02(in1, true);
+  test02(in2, false);
+  test02(in3, false);
+
   return 0;
 }