re PR libstdc++/10132 (filebuf destructor throws exceptions)
authorBenjamin Kosnik <bkoz@redhat.com>
Sat, 26 Apr 2003 00:23:18 +0000 (00:23 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Sat, 26 Apr 2003 00:23:18 +0000 (00:23 +0000)
2003-04-25  Benjamin Kosnik  <bkoz@redhat.com>

PR libstdc++/10132
* include/std/std_fstream.h (basic_filebuf::is_open): Add throw()
exception specifications.
(basic_filebuf::close): Same.
(basic_filebuf::_M_pback_destroy): Same.
(basic_filebuf::_M_destroy_internal_buffer): Same.
(basic_filebuf): Remove __res_type typedef.
* src/fstream.cc: Same.
* include/bits/fstream.tcc
(basic_filebuf::_M_convert_to_external): Simplify.
(basic_filebuf::seekoff): Use has_facet before use_facet.
(basic_filebuf::close): Add exception specification of throw().
* testsuite/27_io/basic_filebuf/cons: New.
* testsuite/27_io/basic_filebuf/cons/wchar_t: New.
* testsuite/27_io/basic_filebuf/cons/wchar_t/10132-1.cc: New.
* testsuite/27_io/basic_filebuf/seekoff/10132-2.cc: New.
* testsuite/27_io/basic_filebuf/seekpos/10132-3.cc: New.

From-SVN: r66091

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/include/std/std_fstream.h
libstdc++-v3/src/fstream.cc
libstdc++-v3/testsuite/27_io/basic_filebuf/cons/wchar_t/10132-1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/10132-2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/seekpos/10132-3.cc [new file with mode: 0644]

index f27bbe2a4a005d133d03268dfb19e93cb32b1faf..c0afcf5d0d12ddc03d42aef04392eb935da5dd10 100644 (file)
@@ -1,3 +1,23 @@
+2003-04-25  Benjamin Kosnik  <bkoz@redhat.com>
+
+       PR libstdc++/10132
+       * include/std/std_fstream.h (basic_filebuf::is_open): Add throw()
+       exception specifications.
+       (basic_filebuf::close): Same.
+       (basic_filebuf::_M_pback_destroy): Same.
+       (basic_filebuf::_M_destroy_internal_buffer): Same.
+       (basic_filebuf): Remove __res_type typedef.     
+       * src/fstream.cc: Same.
+       * include/bits/fstream.tcc
+       (basic_filebuf::_M_convert_to_external): Simplify.
+       (basic_filebuf::seekoff): Use has_facet before use_facet.
+       (basic_filebuf::close): Add exception specification of throw().
+       * testsuite/27_io/basic_filebuf/cons: New.
+       * testsuite/27_io/basic_filebuf/cons/wchar_t: New.      
+       * testsuite/27_io/basic_filebuf/cons/wchar_t/10132-1.cc: New.   
+       * testsuite/27_io/basic_filebuf/seekoff/10132-2.cc: New.
+       * testsuite/27_io/basic_filebuf/seekpos/10132-3.cc: New.
+
 2003-04-25  Benjamin Kosnik  <bkoz@redhat.com>
        
        * include/bits/locale_classes.h
index b68e5a6710a1ffebe514002c9d28508887d5f30a..7a8ae3b2d5a4c38a87342e1d5f724bd3c7b46755 100644 (file)
@@ -60,7 +60,7 @@ namespace std
   template<typename _CharT, typename _Traits>
     void
     basic_filebuf<_CharT, _Traits>::
-    _M_destroy_internal_buffer()
+    _M_destroy_internal_buffer() throw()
     {
       if (_M_buf_allocated)
        {
@@ -114,40 +114,48 @@ namespace std
   template<typename _CharT, typename _Traits>
     typename basic_filebuf<_CharT, _Traits>::__filebuf_type* 
     basic_filebuf<_CharT, _Traits>::
-    close()
+    close() throw()
     {
       __filebuf_type* __ret = NULL;
       if (this->is_open())
        {
          bool __testfail = false;
-         const int_type __eof = traits_type::eof();
-         const bool __testput = this->_M_out_beg < this->_M_out_lim;
+         try
+           {
+             const int_type __eof = traits_type::eof();
+             const bool __testput = this->_M_out_beg < this->_M_out_lim;
 
-         if (__testput 
-             && traits_type::eq_int_type(_M_really_overflow(__eof), __eof))
-           __testfail = true;
+             if (__testput 
+                 && traits_type::eq_int_type(_M_really_overflow(__eof), 
+                                             __eof))
+               __testfail = true;
 
 #if 0
-         // XXX not done
-         if (_M_last_overflowed)
+             // XXX not done
+             if (_M_last_overflowed)
+               {
+                 _M_output_unshift();
+                 _M_really_overflow(__eof);
+               }
+#endif
+           }
+         catch(...)
            {
-             _M_output_unshift();
-             _M_really_overflow(__eof);
+             __testfail = true;
            }
-#endif
-
+             
          // NB: Do this here so that re-opened filebufs will be cool...
          this->_M_mode = ios_base::openmode(0);
          _M_destroy_internal_buffer();
          _M_pback_destroy();
-
+         
          if (!_M_file.close())
            __testfail = true;
 
          if (!__testfail)
            __ret = this;
        }
-      _M_last_overflowed = false;      
+      _M_last_overflowed = false;
       return __ret;
     }
 
@@ -160,8 +168,7 @@ namespace std
       const bool __testin = this->_M_mode & ios_base::in;
       const locale __loc = this->getloc();
       const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
-      // Sync with stdio.
-      const bool __sync = this->_M_buf_size <= 1;
+      const bool __testsync = this->_M_buf_size <= 1;
 
       if (__testin && this->is_open())
        {
@@ -170,7 +177,7 @@ namespace std
          // For a stateful encoding (-1) the pending sequence might be just
          // shift and unshift prefixes with no actual character.
          if (__cvt.encoding() >= 0)
-           __ret += _M_file.showmanyc_helper(__sync) / __cvt.max_length();
+           __ret += _M_file.showmanyc_helper(__testsync) / __cvt.max_length();
        }
 
       _M_last_overflowed = false;      
@@ -283,15 +290,14 @@ namespace std
     _M_convert_to_external(_CharT* __ibuf, streamsize __ilen,
                           streamsize& __elen, streamsize& __plen)
     {
+      const bool __testsync = this->_M_buf_size <= 1;
       const locale __loc = this->getloc();
       const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
-      // Sync with stdio.
-      const bool __sync = this->_M_buf_size <= 1;
 
       if (__cvt.always_noconv() && __ilen)
        {
-         __elen +=
-           _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen, __sync);
+         __elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), 
+                                  __ilen, __testsync);
          __plen += __ilen;
        }
       else
@@ -304,27 +310,30 @@ namespace std
          char* __buf = static_cast<char*>(__builtin_alloca(__blen));
          char* __bend;
          const char_type* __iend;
-         __res_type __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen, 
-                                    __iend, __buf, __buf + __blen, __bend);
-
+         codecvt_base::result __r;
+         __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen,
+                         __iend, __buf, __buf + __blen, __bend);
+         
          if (__r == codecvt_base::ok || __r == codecvt_base::partial)
            __blen = __bend - __buf;
-         // Similarly to the always_noconv case above.
          else if (__r == codecvt_base::noconv)
            {
+             // Same as the always_noconv case above.
              __buf = reinterpret_cast<char*>(__ibuf);
              __blen = __ilen;
            }
-         // Result == error
-         else 
-           __blen = 0;
+         else
+           {
+             // Result == error 
+             __blen = 0;
+           }
          
          if (__blen)
            {
-             __elen += _M_file.xsputn(__buf, __blen, __sync);
+             __elen += _M_file.xsputn(__buf, __blen, __testsync);
              __plen += __blen;
            }
-
+         
          // Try once more for partial conversions.
          if (__r == codecvt_base::partial)
            {
@@ -333,17 +342,9 @@ namespace std
              __r = __cvt.out(_M_state_cur, __iresume, __iresume + __rlen, 
                              __iend, __buf, __buf + __blen, __bend);
              if (__r != codecvt_base::error)
-               __rlen = __bend - __buf;
-             else
-               {
-                 __rlen = 0;
-                 // Signal to the caller (_M_really_overflow) that
-                 // codecvt::out eventually failed.
-                 __elen = 0;             
-               }
-             if (__rlen)
                {
-                 __elen += _M_file.xsputn(__buf, __rlen, __sync);
+                 __rlen = __bend - __buf;
+                 __elen += _M_file.xsputn(__buf, __rlen, __testsync);
                  __plen += __rlen;
                }
            }
@@ -358,8 +359,7 @@ namespace std
       int_type __ret = traits_type::eof();
       const bool __testput = this->_M_out_beg < this->_M_out_lim;
       const bool __testunbuffered = _M_file.is_open() && !this->_M_buf_size;
-      // Sync with stdio.
-      const bool __sync = this->_M_buf_size <= 1;
+      const bool __testsync = this->_M_buf_size <= 1;
 
       if (__testput || __testunbuffered)
        {
@@ -373,7 +373,7 @@ namespace std
          if (_M_filepos && _M_filepos != this->_M_out_beg)
            {
              off_type __off = this->_M_out_beg - _M_filepos;
-             _M_file.seekoff(__off, ios_base::cur, __sync);
+             _M_file.seekoff(__off, ios_base::cur, __testsync);
            }
 
          // Convert internal buffer to external representation, output.
@@ -394,7 +394,8 @@ namespace std
                  char_type __pending = traits_type::to_char_type(__c);
                  _M_convert_to_external(&__pending, 1, __elen, __plen);
 
-                 // User code must flush when switching modes (thus don't sync).
+                 // User code must flush when switching modes (thus
+                 // don't sync).
                  if (__elen == __plen && __elen)
                    {
                      _M_set_indeterminate();
@@ -446,15 +447,15 @@ namespace std
       pos_type __ret =  pos_type(off_type(-1)); 
       const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
       const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
-      // Sync with stdio.
-      const bool __sync = this->_M_buf_size <= 1;
+      const bool __testsync = this->_M_buf_size <= 1;
       
-      // Should probably do has_facet checks here.
-      int __width = use_facet<__codecvt_type>(this->_M_buf_locale).encoding();
+      int __width = 0;
+      if (has_facet<__codecvt_type>(this->_M_buf_locale))
+         __width = use_facet<__codecvt_type>(this->_M_buf_locale).encoding();
       if (__width < 0)
        __width = 0;
-      const bool __testfail = __off != 0 && __width <= 0;
-      
+
+      const bool __testfail = __off != 0 && __width <= 0;      
       if (this->is_open() && !__testfail && (__testin || __testout)) 
        {
          // Ditch any pback buffers to avoid confusion.
@@ -480,22 +481,22 @@ namespace std
                __computed_off += this->_M_in_cur - _M_filepos;
 
              // Return pos_type(off_type(-1)) in case of failure.
-             __ret = _M_file.seekoff(__computed_off, __way, __sync, __mode);
+             __ret = _M_file.seekoff(__computed_off, __way, __testsync, 
+                                     __mode);
              _M_set_indeterminate();
            }
          // NB: Need to do this in case _M_file in indeterminate
          // state, ie _M_file._offset == -1
          else
            {
-             pos_type __tmp =
-               _M_file.seekoff(__off, ios_base::cur,
-                               __sync, __mode);
+             pos_type __tmp = _M_file.seekoff(__off, ios_base::cur, 
+                                              __testsync, __mode);
              if (__tmp >= 0)
                {
                  // Seek successful.
                  __ret = __tmp;
-                 __ret +=
-                   std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos;
+                 __ret += std::max(this->_M_out_cur, this->_M_in_cur) 
+                          - _M_filepos;
                }
            }
        }
index 6be39c69395865d14d9136094d1ef1ed345fc0af..3edfe8d9d24adda45fd9fcbf85f6e8c95cd2dcc9 100644 (file)
@@ -81,7 +81,6 @@ namespace std
       typedef __basic_file<char>                       __file_type;
       typedef typename traits_type::state_type          __state_type;
       typedef codecvt<char_type, char, __state_type>    __codecvt_type;
-      typedef typename __codecvt_type::result          __res_type;
       typedef ctype<char_type>                          __ctype_type;
       //@}
 
@@ -171,7 +170,7 @@ namespace std
       // Assumptions:
       // The pback buffer has only moved forward.
       void
-      _M_pback_destroy()
+      _M_pback_destroy() throw()
       {
        if (_M_pback_init)
          {
@@ -218,7 +217,7 @@ namespace std
        *  @brief  Returns true if the external file is open.
       */
       bool
-      is_open() const { return _M_file.is_open(); }
+      is_open() const throw() { return _M_file.is_open(); }
 
       /**
        *  @brief  Opens an external file.
@@ -248,7 +247,7 @@ namespace std
        *  If any operations fail, this function also fails.
       */
       __filebuf_type*
-      close();
+      close() throw();
 
     protected:
       /**
@@ -265,7 +264,7 @@ namespace std
        *  @endif
       */
       void
-      _M_destroy_internal_buffer();
+      _M_destroy_internal_buffer() throw();
 
       // [27.8.1.4] overridden virtual functions
       // [documentation is inherited]
index e79659d38a723581fb775a5f2a9495d4340e77fd..458e59d94ce1e52027147777fd976c6617353284 100644 (file)
@@ -43,8 +43,7 @@ namespace std
       int_type __ret = traits_type::eof();
       const bool __testin = _M_mode & ios_base::in;
       const bool __testout = _M_mode & ios_base::out;
-      // Sync with stdio.
-      const bool __sync = _M_buf_size <= 1;
+      const bool __testsync = _M_buf_size <= 1;
 
       if (__testin)
        {
@@ -72,7 +71,7 @@ namespace std
                _M_really_overflow();
              else if (_M_in_cur != _M_filepos)
                _M_file.seekoff(_M_in_cur - _M_filepos,
-                               ios_base::cur, __sync, ios_base::in);
+                               ios_base::cur, __testsync, ios_base::in);
            }
 
          if (__testinit || __testget)
@@ -81,7 +80,7 @@ namespace std
              streamsize __ilen = 0;
 
              __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 
-                                     _M_buf_size, __sync);
+                                     _M_buf_size, __testsync);
              __ilen = __elen;
 
              if (0 < __ilen)
@@ -92,7 +91,7 @@ namespace std
                  __ret = traits_type::to_int_type(*_M_in_cur);
                  if (__bump)
                    _M_in_cur_move(1);
-                 else if (__sync)
+                 else if (__testsync)
                    {
                      // If we are synced with stdio, we have to unget the
                      // character we just read so that the file pointer
@@ -125,8 +124,7 @@ namespace std
       int_type __ret = traits_type::eof();
       const bool __testin = _M_mode & ios_base::in;
       const bool __testout = _M_mode & ios_base::out;
-      // Sync with stdio.
-      const bool __sync = _M_buf_size <= 1;
+      const bool __testsync = _M_buf_size <= 1;
 
       if (__testin)
        {
@@ -154,39 +152,39 @@ namespace std
                _M_really_overflow();
              else if (_M_in_cur != _M_filepos)
                _M_file.seekoff(_M_in_cur - _M_filepos,
-                                 ios_base::cur, __sync, ios_base::in);
+                               ios_base::cur, __testsync, ios_base::in);
            }
 
          if (__testinit || __testget)
            {
-             const locale __loc = this->getloc();
-             const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); 
-
              streamsize __elen = 0;
              streamsize __ilen = 0;
+             const locale __loc = this->getloc();
+             const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
              if (__cvt.always_noconv())
                {
                  __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 
-                                         _M_buf_size, __sync);
+                                         _M_buf_size, __testsync);
                  __ilen = __elen;
                }
              else
                {
                  char* __buf = static_cast<char*>(__builtin_alloca(_M_buf_size));
-                 __elen = _M_file.xsgetn(__buf, _M_buf_size, __sync);
-
+                 __elen = _M_file.xsgetn(__buf, _M_buf_size, __testsync);
+                 
                  const char* __eend;
                  char_type* __iend;
-                 __res_type __r = __cvt.in(_M_state_cur, __buf, 
-                                           __buf + __elen, __eend, _M_in_beg
-                                           _M_in_beg + _M_buf_size, __iend);
+                 codecvt_base::result __r;
+                 __r = __cvt.in(_M_state_cur, __buf, __buf + __elen, __eend
+                                _M_in_beg, _M_in_beg + _M_buf_size, __iend);
                  if (__r == codecvt_base::ok)
                    __ilen = __iend - _M_in_beg;
                  else 
                    {
                      // Unwind.
                      __ilen = 0;
-                     _M_file.seekoff(-__elen, ios_base::cur, __sync, ios_base::in);
+                     _M_file.seekoff(-__elen, ios_base::cur, __testsync, 
+                                     ios_base::in);
                    }
                }
 
@@ -198,7 +196,7 @@ namespace std
                  __ret = traits_type::to_int_type(*_M_in_cur);
                  if (__bump)
                    _M_in_cur_move(1);
-                 else if (__sync)
+                 else if (__testsync)
                    {
                      // If we are synced with stdio, we have to unget the
                      // character we just read so that the file pointer
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/cons/wchar_t/10132-1.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/cons/wchar_t/10132-1.cc
new file mode 100644 (file)
index 0000000..c25e002
--- /dev/null
@@ -0,0 +1,54 @@
+// 2003-04-24 Pétur Runólfsson <peturr02@ru.is>
+// 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.
+
+#include <fstream>
+#include <locale>
+#include <stdexcept>
+#include <testsuite_hooks.h>
+
+class Cvt : public std::codecvt<wchar_t, char, std::mbstate_t>
+{
+protected:
+  virtual std::codecvt_base::result
+  do_out(std::mbstate_t&, const wchar_t*, const wchar_t*, const wchar_t*&, 
+        char*, char*, char*&) const
+  { throw std::runtime_error("codecvt failed"); }
+};
+
+int main()
+{
+  using namespace std;
+  bool test = true;
+
+  locale loc = locale(locale::classic(), new Cvt);
+  wfilebuf* fb = new wfilebuf;
+  fb->pubimbue(loc);
+  fb->open("tmp_10132", ios_base::out);
+  fb->sputc(L'a');
+  
+  try
+    {
+      delete fb;
+    }
+  catch(exception& obj)
+    {
+      VERIFY( false ); 
+    }
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/10132-2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/10132-2.cc
new file mode 100644 (file)
index 0000000..e1628c4
--- /dev/null
@@ -0,0 +1,147 @@
+// 2003-04-24 bkoz
+
+// 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.1 - Template class basic_filebuf 
+// NB: This file is for testing basic_filebuf with NO OTHER INCLUDES.
+
+#include <fstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/10132, add on
+class gnu_char_type
+{
+  unsigned long character;
+public:
+  // operator ==
+  bool
+  operator==(const gnu_char_type& __lhs) 
+  { return character == __lhs.character; }
+
+  // operator <
+  bool
+  operator<(const gnu_char_type& __lhs) 
+  { return character < __lhs.character; }
+
+  // default ctor
+  gnu_char_type() { }
+
+  // to_char_type
+  gnu_char_type(const unsigned long& __l) : character(__l) { } 
+
+  // to_int_type
+  operator unsigned long() const { return character; }
+};
+
+// char_traits specialization
+struct gnu_char_traits
+{
+  typedef gnu_char_type        char_type;
+  typedef long                 int_type;
+  typedef long                 pos_type;
+  typedef unsigned long        off_type;
+  typedef long                 state_type;
+  
+  static void 
+  assign(char_type& __c1, const char_type& __c2) { }
+  
+  static bool 
+  eq(const char_type& __c1, const char_type& __c2) { return true; }
+  
+  static bool 
+  lt(const char_type& __c1, const char_type& __c2) { return true; }
+  
+  static int 
+  compare(const char_type* __s1, const char_type* __s2, size_t __n)
+  { return 0; }
+  
+  static size_t
+  length(const char_type* __s) { return 0; }
+  
+  static const char_type* 
+  find(const char_type* __s, size_t __n, const char_type& __a)
+  { return __s; }
+  
+  static char_type* 
+  move(char_type* __s1, const char_type* __s2, size_t __n)
+  { return __s1; }
+  
+  static char_type* 
+  copy(char_type* __s1, const char_type* __s2, size_t __n)
+  { return __s1; }
+  
+  static char_type* 
+  assign(char_type* __s, size_t __n, char_type __a)
+  { return __s; }
+  
+  static char_type 
+  to_char_type(const int_type& __c)
+  { return char_type(); }
+  
+  static int_type 
+  to_int_type(const char_type& __c)
+  { return int_type(); }
+  
+  static bool 
+  eq_int_type(const int_type& __c1, const int_type& __c2)
+  { return true; }
+  
+  static int_type 
+  eof()
+  { return int_type(); }
+  
+  static int_type 
+  not_eof(const int_type& __c)
+  { return int_type(); }
+};
+
+void test07()
+{
+  bool test = true;
+  typedef std::basic_filebuf<gnu_char_type, gnu_char_traits> gnu_filebuf;
+  
+  try
+    { 
+      // Need codecvt facet for width argument in seekoff.
+      gnu_filebuf obj;
+      obj.pubseekoff(2, std::ios_base::beg);
+    }
+  catch(std::exception& obj)
+    { 
+      test = false; 
+      VERIFY( test );
+    }
+}
+
+#if !__GXX_WEAK__
+// Explicitly instantiate for systems with no COMDAT or weak support.
+template 
+  std::basic_filebuf<gnu_char_type>::int_type
+  std::basic_filebuf<gnu_char_type>::_S_pback_size;
+#endif
+
+int main() 
+{
+  test07();
+  return 0;
+}
+
+
+
+// more surf!!!
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekpos/10132-3.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekpos/10132-3.cc
new file mode 100644 (file)
index 0000000..0f1ee2e
--- /dev/null
@@ -0,0 +1,147 @@
+// 2003-04-24 bkoz
+
+// 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.1 - Template class basic_filebuf 
+// NB: This file is for testing basic_filebuf with NO OTHER INCLUDES.
+
+#include <fstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/10132, add on
+class gnu_char_type
+{
+  unsigned long character;
+public:
+  // operator ==
+  bool
+  operator==(const gnu_char_type& __lhs) 
+  { return character == __lhs.character; }
+
+  // operator <
+  bool
+  operator<(const gnu_char_type& __lhs) 
+  { return character < __lhs.character; }
+
+  // default ctor
+  gnu_char_type() { }
+
+  // to_char_type
+  gnu_char_type(const unsigned long& __l) : character(__l) { } 
+
+  // to_int_type
+  operator unsigned long() const { return character; }
+};
+
+// char_traits specialization
+struct gnu_char_traits
+{
+  typedef gnu_char_type        char_type;
+  typedef long                 int_type;
+  typedef long                 pos_type;
+  typedef unsigned long        off_type;
+  typedef long                 state_type;
+  
+  static void 
+  assign(char_type& __c1, const char_type& __c2) { }
+  
+  static bool 
+  eq(const char_type& __c1, const char_type& __c2) { return true; }
+  
+  static bool 
+  lt(const char_type& __c1, const char_type& __c2) { return true; }
+  
+  static int 
+  compare(const char_type* __s1, const char_type* __s2, size_t __n)
+  { return 0; }
+  
+  static size_t
+  length(const char_type* __s) { return 0; }
+  
+  static const char_type* 
+  find(const char_type* __s, size_t __n, const char_type& __a)
+  { return __s; }
+  
+  static char_type* 
+  move(char_type* __s1, const char_type* __s2, size_t __n)
+  { return __s1; }
+  
+  static char_type* 
+  copy(char_type* __s1, const char_type* __s2, size_t __n)
+  { return __s1; }
+  
+  static char_type* 
+  assign(char_type* __s, size_t __n, char_type __a)
+  { return __s; }
+  
+  static char_type 
+  to_char_type(const int_type& __c)
+  { return char_type(); }
+  
+  static int_type 
+  to_int_type(const char_type& __c)
+  { return int_type(); }
+  
+  static bool 
+  eq_int_type(const int_type& __c1, const int_type& __c2)
+  { return true; }
+  
+  static int_type 
+  eof()
+  { return int_type(); }
+  
+  static int_type 
+  not_eof(const int_type& __c)
+  { return int_type(); }
+};
+
+void test07()
+{
+  bool test = true;
+  typedef std::basic_filebuf<gnu_char_type, gnu_char_traits> gnu_filebuf;
+  
+  try
+    { 
+      // Need codecvt facet for width argument in seekpos.
+      gnu_filebuf obj;
+      obj.pubseekpos(0);
+    }
+  catch(std::exception& obj)
+    { 
+      test = false; 
+      VERIFY( test );
+    }
+}
+
+#if !__GXX_WEAK__
+// Explicitly instantiate for systems with no COMDAT or weak support.
+template 
+  std::basic_filebuf<gnu_char_type>::int_type
+  std::basic_filebuf<gnu_char_type>::_S_pback_size;
+#endif
+
+int main() 
+{
+  test07();
+  return 0;
+}
+
+
+
+// more surf!!!