[multiple changes]
authorBenjamin Kosnik <bkoz@gcc.gnu.org>
Sat, 8 Jun 2002 15:14:56 +0000 (15:14 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Sat, 8 Jun 2002 15:14:56 +0000 (15:14 +0000)
2002-06-08  Paolo Carlini  <pcarlini@unitus.it>

* testsuite/backwards/strstream_members.cc: New.

2002-06-08  Benjamin Kosnik  <bkoz@redhat.com>

* include/backwards/strstream: Format.
* src/strstream.cc: Format.

2002-06-08  Andreas Schwab  <schwab@suse.de>

* src/strstream.cc (strstreambuf::overflow): Set _M_buf,
_M_buf_size and _M_buf_size_opt to the new buffer and size.

From-SVN: r54375

libstdc++-v3/ChangeLog
libstdc++-v3/include/backward/strstream
libstdc++-v3/src/strstream.cc
libstdc++-v3/testsuite/backward/strstream_members.cc [new file with mode: 0644]

index 723d051..3fc972c 100644 (file)
@@ -1,3 +1,17 @@
+2002-06-08  Paolo Carlini  <pcarlini@unitus.it>
+
+       * testsuite/backwards/strstream_members.cc: New.
+
+2002-06-08  Benjamin Kosnik  <bkoz@redhat.com>
+
+       * include/backwards/strstream: Format.
+       * src/strstream.cc: Format.
+       
+2002-06-08  Andreas Schwab  <schwab@suse.de>
+
+       * src/strstream.cc (strstreambuf::overflow): Set _M_buf,
+       _M_buf_size and _M_buf_size_opt to the new buffer and size.
+
 2002-06-08  Benjamin Kosnik  <bkoz@redhat.com>
 
        * config/os/generic/bits/ctype_noninline.h: Tweak format.
index 28308e3..165c6e7 100644 (file)
@@ -1,6 +1,6 @@
 // Backward-compat support -*- C++ -*-
 
-// 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
 
 namespace std
 {
-
-//----------------------------------------------------------------------
-// Class strstreambuf, a streambuf class that manages an array of char.
-// Note that this class is not a template.
-
-class strstreambuf : public basic_streambuf<char, char_traits<char> >
-{
-public:                         // Types.
-  typedef char_traits<char>              _Traits;
-  typedef basic_streambuf<char, _Traits> _Base;
-
-public:                         // Constructor, destructor
-  explicit strstreambuf(streamsize __initial_capacity = 0);
-  strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*));
-
-  strstreambuf(char* __get, streamsize __n, char* __put = 0);
-  strstreambuf(signed char* __get, streamsize __n, signed char* __put = 0);
-  strstreambuf(unsigned char* __get, streamsize __n, unsigned char* __put=0);
-
-  strstreambuf(const char* __get, streamsize __n);
-  strstreambuf(const signed char* __get, streamsize __n);
-  strstreambuf(const unsigned char* __get, streamsize __n);
-
-  virtual ~strstreambuf();
-
-public:                         // strstreambuf operations.
-  void freeze(bool = true);
-  char* str();
-  int pcount() const;
-
-protected:                      // Overridden virtual member functions.
-  virtual int_type overflow(int_type __c  = _Traits::eof());
-  virtual int_type pbackfail(int_type __c = _Traits::eof());
-  virtual int_type underflow();
-  virtual _Base* setbuf(char* __buf, streamsize __n);
-  virtual pos_type seekoff(off_type __off, ios_base::seekdir __dir,
-                           ios_base::openmode __mode
-                                      = ios_base::in | ios_base::out);
-  virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode
-                                      = ios_base::in | ios_base::out);
-
-private:                        // Helper functions.
-  // Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun.
-  char* _M_alloc(size_t);
-  void  _M_free(char*);
-
-  // Helper function used in constructors.
-  void _M_setup(char* __get, char* __put, streamsize __n);
-
-private:                        // Data members.
-  void* (*_M_alloc_fun)(size_t);
-  void  (*_M_free_fun)(void*);
-
-  bool _M_dynamic  : 1;
-  bool _M_frozen   : 1;
-  bool _M_constant : 1;
-};
-
-//----------------------------------------------------------------------
-// Class istrstream, an istream that manages a strstreambuf.
-
-class istrstream : public basic_istream<char>
-{
-public:
-  explicit istrstream(char*);
-  explicit istrstream(const char*);
-  istrstream(char* , streamsize);
-  istrstream(const char*, streamsize);
-  virtual ~istrstream();
-
-  strstreambuf* rdbuf() const;
-  char* str();
-
-private:
-  strstreambuf _M_buf;
-};
-
-//----------------------------------------------------------------------
-// Class ostrstream
-
-class ostrstream : public basic_ostream<char>
-{
-public:
-  ostrstream();
-  ostrstream(char*, int, ios_base::openmode = ios_base::out);
-  virtual ~ostrstream();
-
-  strstreambuf* rdbuf() const;
-  void freeze(bool = true);
-  char* str();
-  int pcount() const;
-
-private:
-  strstreambuf _M_buf;
-};
-
-//----------------------------------------------------------------------
-// Class strstream
-
-class strstream : public basic_iostream<char>
-{
-public:
-  typedef char                        char_type;
-  typedef char_traits<char>::int_type int_type;
-  typedef char_traits<char>::pos_type pos_type;
-  typedef char_traits<char>::off_type off_type;
-
-  strstream();
-  strstream(char*, int, ios_base::openmode = ios_base::in | ios_base::out);
-  virtual ~strstream();
-
-  strstreambuf* rdbuf() const;
-  void freeze(bool = true);
-  int pcount() const;
-  char* str();
-
-private:
-  strstreambuf _M_buf;
-};
-
+  // Class strstreambuf, a streambuf class that manages an array of char.
+  // Note that this class is not a template.
+  class strstreambuf : public basic_streambuf<char, char_traits<char> >
+  {
+  public:                         
+    // Types.
+    typedef char_traits<char>              _Traits;
+    typedef basic_streambuf<char, _Traits> _Base;
+
+  public:  
+    // Constructor, destructor
+    explicit strstreambuf(streamsize __initial_capacity = 0);
+    strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*));
+
+    strstreambuf(char* __get, streamsize __n, char* __put = 0);
+    strstreambuf(signed char* __get, streamsize __n, signed char* __put = 0);
+    strstreambuf(unsigned char* __get, streamsize __n, unsigned char* __put=0);
+
+    strstreambuf(const char* __get, streamsize __n);
+    strstreambuf(const signed char* __get, streamsize __n);
+    strstreambuf(const unsigned char* __get, streamsize __n);
+
+    virtual ~strstreambuf();
+
+  public:
+    void freeze(bool = true);
+    char* str();
+    int pcount() const;
+
+  protected:
+    virtual int_type overflow(int_type __c  = _Traits::eof());
+    virtual int_type pbackfail(int_type __c = _Traits::eof());
+    virtual int_type underflow();
+    virtual _Base* setbuf(char* __buf, streamsize __n);
+    virtual pos_type seekoff(off_type __off, ios_base::seekdir __dir,
+                            ios_base::openmode __mode
+                            = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode
+                            = ios_base::in | ios_base::out);
+
+  private:  
+    // Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun.
+    char* _M_alloc(size_t);
+    void  _M_free(char*);
+
+    // Helper function used in constructors.
+    void _M_setup(char* __get, char* __put, streamsize __n);
+
+  private:  
+    // Data members.
+    void* (*_M_alloc_fun)(size_t);
+    void  (*_M_free_fun)(void*);
+
+    bool _M_dynamic  : 1;
+    bool _M_frozen   : 1;
+    bool _M_constant : 1;
+  };
+
+  // Class istrstream, an istream that manages a strstreambuf.
+  class istrstream : public basic_istream<char>
+  {
+  public:
+    explicit istrstream(char*);
+    explicit istrstream(const char*);
+    istrstream(char* , streamsize);
+    istrstream(const char*, streamsize);
+    virtual ~istrstream();
+
+    strstreambuf* rdbuf() const;
+    char* str();
+
+  private:
+    strstreambuf _M_buf;
+  };
+
+  // Class ostrstream
+  class ostrstream : public basic_ostream<char>
+  {
+  public:
+    ostrstream();
+    ostrstream(char*, int, ios_base::openmode = ios_base::out);
+    virtual ~ostrstream();
+
+    strstreambuf* rdbuf() const;
+    void freeze(bool = true);
+    char* str();
+    int pcount() const;
+
+  private:
+    strstreambuf _M_buf;
+  };
+
+  // Class strstream
+  class strstream : public basic_iostream<char>
+  {
+  public:
+    typedef char                        char_type;
+    typedef char_traits<char>::int_type int_type;
+    typedef char_traits<char>::pos_type pos_type;
+    typedef char_traits<char>::off_type off_type;
+
+    strstream();
+    strstream(char*, int, ios_base::openmode = ios_base::in | ios_base::out);
+    virtual ~strstream();
+
+    strstreambuf* rdbuf() const;
+    void freeze(bool = true);
+    int pcount() const;
+    char* str();
+
+  private:
+    strstreambuf _M_buf;
+  };
 } // namespace std
-
-#endif /* __SGI_STL_STRSTREAM */
-
-// Local Variables:
-// mode:C++
-// End:
-
-
+#endif 
index 7bd8d9c..961ff03 100644 (file)
@@ -1,6 +1,6 @@
 // strstream definitions -*- C++ -*-
 
-// Copyright (C) 2001 Free Software Foundation
+// Copyright (C) 2001, 2002 Free Software Foundation
 //
 // This file is part of GNU CC.
 //
 
 namespace std
 {
-
-// strstreambuf constructor, destructor.
-
-strstreambuf::strstreambuf(streamsize initial_capacity)
-  : _Base(),
-    _M_alloc_fun(0), _M_free_fun(0),
-    _M_dynamic(true), _M_frozen(false), _M_constant(false)
-{
-  _M_buf_size = _M_buf_size_opt = max(initial_capacity, streamsize(16));
-  _M_buf = _M_alloc(_M_buf_size);
-  if (_M_buf) 
-    {
-      setp(_M_buf, _M_buf + _M_buf_size);
-      setg(_M_buf, _M_buf, _M_buf);
-    }
-}
-
-strstreambuf::strstreambuf(void* (*alloc_f)(size_t), void (*free_f)(void*))
-  : _Base(),
-    _M_alloc_fun(alloc_f), _M_free_fun(free_f),
-    _M_dynamic(true), _M_frozen(false), _M_constant(false)
-{
-  _M_buf_size = _M_buf_size_opt = 16;
-  _M_buf = _M_alloc(_M_buf_size);
-  if (_M_buf) 
-    {
-      setp(_M_buf, _M_buf + _M_buf_size);
-      setg(_M_buf, _M_buf, _M_buf);
+  strstreambuf::strstreambuf(streamsize initial_capacity)
+  : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(true), 
+    _M_frozen(false), _M_constant(false)
+  {
+    _M_buf_size = _M_buf_size_opt = max(initial_capacity, streamsize(16));
+    _M_buf = _M_alloc(_M_buf_size);
+    if (_M_buf) 
+      {
+       setp(_M_buf, _M_buf + _M_buf_size);
+       setg(_M_buf, _M_buf, _M_buf);
+      }
   }
-}
-
-strstreambuf::strstreambuf(char* get, streamsize n, char* put)
-  : _Base(),
-    _M_alloc_fun(0), _M_free_fun(0),
-    _M_dynamic(false), _M_frozen(false), _M_constant(false)
-{
-  _M_setup(get, put, n);
-}
-
-strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put)
-  : _Base(),
-    _M_alloc_fun(0), _M_free_fun(0),
-    _M_dynamic(false), _M_frozen(false), _M_constant(false)
-{
-  _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n);
-}
-
-strstreambuf::strstreambuf(unsigned char* get, streamsize n,
-                           unsigned char* put)
-  : _Base(),
-    _M_alloc_fun(0), _M_free_fun(0),
-    _M_dynamic(false), _M_frozen(false), _M_constant(false)
-{
-  _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n);
-}
-
-strstreambuf::strstreambuf(const char* get, streamsize n)
-  : _Base(),
-    _M_alloc_fun(0), _M_free_fun(0),
-    _M_dynamic(false), _M_frozen(false), _M_constant(true)
-{
-  _M_setup(const_cast<char*>(get), 0, n);
-}
 
-strstreambuf::strstreambuf(const signed char* get, streamsize n)
-  : _Base(),
-    _M_alloc_fun(0), _M_free_fun(0),
-    _M_dynamic(false), _M_frozen(false), _M_constant(true)
-{
-  _M_setup(reinterpret_cast<char*>(const_cast<signed char*>(get)), 0, n);
-}
-
-strstreambuf::strstreambuf(const unsigned char* get, streamsize n)
-  : _Base(),
-    _M_alloc_fun(0), _M_free_fun(0),
-    _M_dynamic(false), _M_frozen(false), _M_constant(true)
-{
-  _M_setup(reinterpret_cast<char*>(const_cast<unsigned char*>(get)), 0, n);
-}
-
-strstreambuf::~strstreambuf()
-{
-  if (_M_dynamic && !_M_frozen)
-    {
-      char* p = this->eback();
-      _M_free(p);
-      if (p == _M_buf)
-       _M_buf = 0;
-    }
-  if (_M_buf)
-    _M_free(_M_buf);
-}
-
-void strstreambuf::freeze(bool frozenflag)
-{
-  if (_M_dynamic)
-    _M_frozen = frozenflag;
-}
-
-char* strstreambuf::str()
-{
-  freeze(true);
-  return eback();
-}
-
-int strstreambuf::pcount() const
-{
-  return pptr() ? pptr() - pbase() : 0;
-}
-
-strstreambuf::int_type strstreambuf::overflow(int_type c) {
-  if (c == traits_type::eof())
-    return traits_type::not_eof(c);
-
-  // Try to expand the buffer.
-  if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant) {
-    ptrdiff_t old_size = epptr() - pbase();
-    ptrdiff_t new_size = max(2 * old_size, ptrdiff_t(1));
-
-    char* buf = _M_alloc(new_size);
-    if (buf) {
-      memcpy(buf, pbase(), old_size);
-
-      char* old_buffer = pbase();
-      bool reposition_get = false;
-      ptrdiff_t old_get_offset;
-      if (gptr() != 0) {
-        reposition_get = true;
-        old_get_offset = gptr() - eback();
+  strstreambuf::strstreambuf(void* (*alloc_f)(size_t), void (*free_f)(void*))
+  : _Base(), _M_alloc_fun(alloc_f), _M_free_fun(free_f), _M_dynamic(true), 
+    _M_frozen(false), _M_constant(false)
+  {
+    _M_buf_size = _M_buf_size_opt = 16;
+    _M_buf = _M_alloc(_M_buf_size);
+    if (_M_buf) 
+      {
+       setp(_M_buf, _M_buf + _M_buf_size);
+       setg(_M_buf, _M_buf, _M_buf);
       }
-
-      setp(buf, buf + new_size);
-      pbump(old_size);
-
-      if (reposition_get)
-        setg(buf, buf + old_get_offset, buf + max(old_get_offset, old_size));
-
-      _M_free(old_buffer);
-    }
   }
 
-  if (pptr() != epptr()) {
-    *pptr() = c;
-    pbump(1);
-    return c;
+  strstreambuf::strstreambuf(char* get, streamsize n, char* put)
+  : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
+    _M_frozen(false), _M_constant(false)
+  { _M_setup(get, put, n); }
+
+  strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put)
+  : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
+  _M_frozen(false), _M_constant(false)
+  { _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n); }
+
+  strstreambuf::strstreambuf(unsigned char* get, streamsize n, 
+                            unsigned char* put)
+  : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
+    _M_frozen(false), _M_constant(false)
+  { _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n); }
+
+  strstreambuf::strstreambuf(const char* get, streamsize n)
+  : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
+    _M_frozen(false), _M_constant(true)
+  { _M_setup(const_cast<char*>(get), 0, n); }
+
+  strstreambuf::strstreambuf(const signed char* get, streamsize n)
+  : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
+    _M_frozen(false), _M_constant(true)
+  { _M_setup(reinterpret_cast<char*>(const_cast<signed char*>(get)), 0, n); }
+
+  strstreambuf::strstreambuf(const unsigned char* get, streamsize n)
+  : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
+    _M_frozen(false), _M_constant(true)
+  { _M_setup(reinterpret_cast<char*>(const_cast<unsigned char*>(get)), 0, n); }
+
+  strstreambuf::~strstreambuf()
+  {
+    if (_M_dynamic && !_M_frozen)
+      {
+       char* p = this->eback();
+       _M_free(p);
+       if (p == _M_buf)
+         _M_buf = 0;
+      }
+    if (_M_buf)
+      _M_free(_M_buf);
   }
-  else
-    return traits_type::eof();
-}
 
-strstreambuf::int_type strstreambuf::pbackfail(int_type c)
-{
-  if (gptr() != eback()) {
-    if (c == _Traits::eof()) {
-      gbump(-1);
-      return _Traits::not_eof(c);
-    }
-    else if (c == static_cast<int_type>(gptr()[-1])) {  // KLUDGE
-      gbump(-1);
-      return c;
-    }
-    else if (!_M_constant) {
-      gbump(-1);
-      *gptr() = c;
-      return c;
-    }
+  void 
+  strstreambuf::freeze(bool frozenflag)
+  {
+    if (_M_dynamic)
+      _M_frozen = frozenflag;
   }
 
-  return _Traits::eof();
-}
-
-strstreambuf::int_type strstreambuf::underflow()
-{
-  if (gptr() == egptr() && pptr() && pptr() > egptr())
-    setg(eback(), gptr(), pptr());
-
-  if (gptr() != egptr())
-    return (unsigned char) *gptr();
-  else
-    return _Traits::eof();
-}
-
-basic_streambuf<char, char_traits<char> >*
-strstreambuf::setbuf(char*, streamsize)
-{
-  return this;
-}
-
-strstreambuf::pos_type
-strstreambuf::seekoff(off_type off,
-                      ios_base::seekdir dir, ios_base::openmode mode)
-{
-  bool do_get = false;
-  bool do_put = false;
-
-  if ((mode & (ios_base::in | ios_base::out)) ==
-          (ios_base::in | ios_base::out) &&
-      (dir == ios_base::beg || dir == ios_base::end))
-    do_get = do_put = true;
-  else if (mode & ios_base::in)
-    do_get = true;
-  else if (mode & ios_base::out)
-    do_put = true;
-
-  // !gptr() is here because, according to D.7.1 paragraph 4, the seekable
-  // area is undefined if there is no get area.
-  if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr())
-    return pos_type(off_type(-1));
-
-  char* seeklow  = eback();
-  char* seekhigh = epptr() ? epptr() : egptr();
-
-  off_type newoff;
-  switch(dir) {
-  case ios_base::beg:
-    newoff = 0;
-    break;
-  case ios_base::end:
-    newoff = seekhigh - seeklow;
-    break;
-  case ios_base::cur:
-    newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
-    break;
-  default:
-    return pos_type(off_type(-1));
+  char* 
+  strstreambuf::str()
+  {
+    freeze(true);
+    return eback();
   }
 
-  off += newoff;
-  if (off < 0 || off > seekhigh - seeklow)
-    return pos_type(off_type(-1));
+  int 
+  strstreambuf::pcount() const
+  { return pptr() ? pptr() - pbase() : 0; }
+
+  strstreambuf::int_type 
+  strstreambuf::overflow(int_type c) 
+  {
+    if (c == traits_type::eof())
+      return traits_type::not_eof(c);
+    
+    // Try to expand the buffer.
+    if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant) 
+      {
+       ptrdiff_t old_size = epptr() - pbase();
+       ptrdiff_t new_size = max(2 * old_size, ptrdiff_t(1));
+       
+       char* buf = _M_alloc(new_size);
+       if (buf) 
+         {
+           memcpy(buf, pbase(), old_size);
+           char* old_buffer = pbase();
+           bool reposition_get = false;
+           ptrdiff_t old_get_offset;
+           if (gptr() != 0) 
+             {
+               reposition_get = true;
+               old_get_offset = gptr() - eback();
+             }
+           
+           _M_buf = buf;
+           _M_buf_size = _M_buf_size_opt = new_size;
+           setp(buf, buf + new_size);
+           pbump(old_size);
+
+           if (reposition_get)
+             setg(buf, buf + old_get_offset, buf + 
+                  max(old_get_offset, old_size));
+
+           _M_free(old_buffer);
+         }
+      }
+    
+    if (pptr() != epptr()) 
+      {
+       *pptr() = c;
+       pbump(1);
+       return c;
+      }
+    else
+      return traits_type::eof();
+  }
 
-  if (do_put) {
-    if (seeklow + off < pbase()) {
-      setp(seeklow, epptr());
-      pbump(off);
-    }
-    else {
-      setp(pbase(), epptr());
-      pbump(off - (pbase() - seeklow));
+  strstreambuf::int_type 
+  strstreambuf::pbackfail(int_type c)
+  {
+    if (gptr() != eback()) 
+      {
+      if (c == _Traits::eof()) 
+       {
+         gbump(-1);
+         return _Traits::not_eof(c);
+       }
+      else if (c == static_cast<int_type>(gptr()[-1])) 
+       {  // KLUDGE
+         gbump(-1);
+         return c;
+       }
+      else if (!_M_constant) 
+       {
+         gbump(-1);
+         *gptr() = c;
+         return c;
+       }
     }
+    return _Traits::eof();
   }
-  if (do_get) {
-    if (off <= egptr() - seeklow)
-      setg(seeklow, seeklow + off, egptr());
-    else if (off <= pptr() - seeklow)
-      setg(seeklow, seeklow + off, pptr());
+
+  strstreambuf::int_type 
+  strstreambuf::underflow()
+  {
+    if (gptr() == egptr() && pptr() && pptr() > egptr())
+      setg(eback(), gptr(), pptr());
+    
+    if (gptr() != egptr())
+      return (unsigned char) *gptr();
     else
-      setg(seeklow, seeklow + off, epptr());
+      return _Traits::eof();
   }
 
-  return pos_type(newoff);
-}
-
-strstreambuf::pos_type
-strstreambuf::seekpos(pos_type pos, ios_base::openmode mode)
-{
-  return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode);
-}
+  basic_streambuf<char, char_traits<char> >*
+  strstreambuf::setbuf(char*, streamsize)
+  { return this; }
+
+  strstreambuf::pos_type
+  strstreambuf::seekoff(off_type off, ios_base::seekdir dir, 
+                       ios_base::openmode mode)
+  {
+    bool do_get = false;
+    bool do_put = false;
+
+    if ((mode & (ios_base::in | ios_base::out)) 
+       == (ios_base::in | ios_base::out) &&
+       (dir == ios_base::beg || dir == ios_base::end))
+      do_get = do_put = true;
+    else if (mode & ios_base::in)
+      do_get = true;
+    else if (mode & ios_base::out)
+      do_put = true;
+
+    // !gptr() is here because, according to D.7.1 paragraph 4, the seekable
+    // area is undefined if there is no get area.
+    if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr())
+      return pos_type(off_type(-1));
+
+    char* seeklow  = eback();
+    char* seekhigh = epptr() ? epptr() : egptr();
+
+    off_type newoff;
+    switch (dir) 
+      {
+      case ios_base::beg:
+       newoff = 0;
+       break;
+      case ios_base::end:
+       newoff = seekhigh - seeklow;
+       break;
+      case ios_base::cur:
+       newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
+       break;
+      default:
+       return pos_type(off_type(-1));
+      }
+    
+    off += newoff;
+    if (off < 0 || off > seekhigh - seeklow)
+      return pos_type(off_type(-1));
+
+    if (do_put) 
+      {
+       if (seeklow + off < pbase()) 
+         {
+           setp(seeklow, epptr());
+           pbump(off);
+         }
+       else 
+         {
+           setp(pbase(), epptr());
+           pbump(off - (pbase() - seeklow));
+         }
+      }
+    if (do_get) 
+      {
+       if (off <= egptr() - seeklow)
+         setg(seeklow, seeklow + off, egptr());
+       else if (off <= pptr() - seeklow)
+         setg(seeklow, seeklow + off, pptr());
+       else
+         setg(seeklow, seeklow + off, epptr());
+      }
+    return pos_type(newoff);
+  }
 
-char* strstreambuf::_M_alloc(size_t n)
-{
-  if (_M_alloc_fun)
-    return static_cast<char*>(_M_alloc_fun(n));
-  else
-    return new char[n];
-}
+  strstreambuf::pos_type
+  strstreambuf::seekpos(pos_type pos, ios_base::openmode mode)
+  { return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode); }
 
-void strstreambuf::_M_free(char* p)
-{
-  if (p)
-    if (_M_free_fun)
-      _M_free_fun(p);
+  char* 
+  strstreambuf::_M_alloc(size_t n)
+  {
+    if (_M_alloc_fun)
+      return static_cast<char*>(_M_alloc_fun(n));
     else
-      delete[] p;
-}
-
-void strstreambuf::_M_setup(char* get, char* put, streamsize n)
-{
-  if (get) {
-    size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
+      return new char[n];
+  }
 
-    if (put) {
-      setg(get, get, put);
-      setp(put, put + N);
-    }
-    else {
-      setg(get, get, get + N);
-    }
+  void 
+  strstreambuf::_M_free(char* p)
+  {
+    if (p)
+      if (_M_free_fun)
+       _M_free_fun(p);
+      else
+       delete[] p;
   }
-}
 
-//----------------------------------------------------------------------
-// Class istrstream
+  void 
+  strstreambuf::_M_setup(char* get, char* put, streamsize n)
+  {
+    if (get) 
+      {
+       size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
+       
+       if (put) 
+         {
+           setg(get, get, put);
+           setp(put, put + N);
+         }
+       else 
+         setg(get, get, get + N);
+      }
+  }
 
-istrstream::istrstream(char* s)
+  istrstream::istrstream(char* s)
   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
-{
-  basic_ios<char>::init(&_M_buf);
-}
+  { basic_ios<char>::init(&_M_buf); }
 
-istrstream::istrstream(const char* s)
+  istrstream::istrstream(const char* s)
   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
-{
-  basic_ios<char>::init(&_M_buf);
-}
+  { basic_ios<char>::init(&_M_buf); }
 
-istrstream::istrstream(char* s, streamsize n)
+  istrstream::istrstream(char* s, streamsize n)
   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
-{
-  basic_ios<char>::init(&_M_buf);
-}
+  { basic_ios<char>::init(&_M_buf); }
 
-istrstream::istrstream(const char* s, streamsize n)
+  istrstream::istrstream(const char* s, streamsize n)
   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
-{
-  basic_ios<char>::init(&_M_buf);
-}
-
-istrstream::~istrstream() {}
+  { basic_ios<char>::init(&_M_buf); }
 
-strstreambuf* istrstream::rdbuf() const {
-  return const_cast<strstreambuf*>(&_M_buf);
-}
+  istrstream::~istrstream() { }
 
-char* istrstream::str() { return _M_buf.str(); }
+  strstreambuf* 
+  istrstream::rdbuf() const 
+  { return const_cast<strstreambuf*>(&_M_buf); }
 
-//----------------------------------------------------------------------
-// Class ostrstream
+  char* 
+  istrstream::str() 
+  { return _M_buf.str(); }
 
-ostrstream::ostrstream()
+  ostrstream::ostrstream()
   : basic_ios<char>(), basic_ostream<char>(0), _M_buf()
-{
-  basic_ios<char>::init(&_M_buf);
-}
+  { basic_ios<char>::init(&_M_buf); }
 
-ostrstream::ostrstream(char* s, int n, ios_base::openmode mode)
-  : basic_ios<char>(), basic_ostream<char>(0),
+  ostrstream::ostrstream(char* s, int n, ios_base::openmode mode)
+  : basic_ios<char>(), basic_ostream<char>(0), 
     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
-{
-  basic_ios<char>::init(&_M_buf);
-}
+  { basic_ios<char>::init(&_M_buf); }
 
-ostrstream::~ostrstream() {}
+  ostrstream::~ostrstream() {}
 
-strstreambuf* ostrstream::rdbuf() const
-{
-  return const_cast<strstreambuf*>(&_M_buf);
-}
+  strstreambuf* 
+  ostrstream::rdbuf() const
+  { return const_cast<strstreambuf*>(&_M_buf); }
 
-void ostrstream::freeze(bool freezeflag)
-{
-  _M_buf.freeze(freezeflag);
-}
+  void 
+  ostrstream::freeze(bool freezeflag)
+  { _M_buf.freeze(freezeflag); }
 
-char* ostrstream::str()
-{
-  return _M_buf.str();
-}
+  char* 
+  ostrstream::str()
+  { return _M_buf.str(); }
 
-int ostrstream::pcount() const
-{
-  return _M_buf.pcount();
-}
-
-//----------------------------------------------------------------------
-// Class strstream
+  int 
+  ostrstream::pcount() const
+  { return _M_buf.pcount(); }
 
-strstream::strstream()
+  strstream::strstream()
   : basic_ios<char>(), basic_iostream<char>(0), _M_buf()
-{
-  basic_ios<char>::init(&_M_buf);
-}
+  { basic_ios<char>::init(&_M_buf); }
 
-strstream::strstream(char* s, int n, ios_base::openmode mode)
-  : basic_ios<char>(), basic_iostream<char>(0),
+  strstream::strstream(char* s, int n, ios_base::openmode mode)
+  : basic_ios<char>(), basic_iostream<char>(0), 
     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
-{
-  basic_ios<char>::init(&_M_buf);
-}
-
-strstream::~strstream() {}
+  { basic_ios<char>::init(&_M_buf); }
 
-strstreambuf* strstream::rdbuf() const
-{
-  return const_cast<strstreambuf*>(&_M_buf);
-}
+  strstream::~strstream() { }
 
-void strstream::freeze(bool freezeflag)
-{
-  _M_buf.freeze(freezeflag);
-}
+  strstreambuf* 
+  strstream::rdbuf() const
+  { return const_cast<strstreambuf*>(&_M_buf); }
 
-int strstream::pcount() const
-{
-  return _M_buf.pcount();
-}
+  void 
+  strstream::freeze(bool freezeflag)
+  { _M_buf.freeze(freezeflag); }
 
-char* strstream::str()
-{
-  return _M_buf.str();
-}
+  int 
+  strstream::pcount() const
+  { return _M_buf.pcount(); }
 
+  char* 
+  strstream::str()
+  { return _M_buf.str(); }
 } // namespace std
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/libstdc++-v3/testsuite/backward/strstream_members.cc b/libstdc++-v3/testsuite/backward/strstream_members.cc
new file mode 100644 (file)
index 0000000..494008e
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (C) 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
+// 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.
+
+// backward strstream members
+
+#include <strstream.h>
+#include <testsuite_hooks.h>
+
+// { dg-options "-Wno-deprecated" }
+
+int test01()
+{
+   strstream s;
+   for (unsigned i=0 ; i!= 1000 ; ++i)
+      s << i << std::endl;
+   s << std::ends;
+
+   return 0;
+}
+
+int main()
+{
+  test01();
+  return 0;
+}