basic_ios.tcc: Formatting tweaks.
authorBenjamin Kosnik <bkoz@redhat.com>
Wed, 6 Jun 2001 01:31:58 +0000 (01:31 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Wed, 6 Jun 2001 01:31:58 +0000 (01:31 +0000)
2001-06-05  Benjamin Kosnik  <bkoz@redhat.com>

libstdc++/3045
* include/bits/basic_ios.tcc: Formatting tweaks.
* include/bits/ios_base.h: Formatting tweaks.
* src/ios.cc (ios_base::Init::_S_ios_create): Use filebufs here.
(ios_base::Init::_S_ios_destroy): ..and here. Explicitly call dtors.
* src/globals.cc: Allocate filebufs for standard streams here.
(buf_cout, buf_cin, buf_cerr): Like so.
(buf_wcout, buf_wcin, buf_wcerr): And so.
* testsuite/27_io/ios_init.cc: Add.

From-SVN: r42922

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_ios.tcc
libstdc++-v3/include/bits/ios_base.h
libstdc++-v3/src/globals.cc
libstdc++-v3/src/ios.cc
libstdc++-v3/testsuite/27_io/ios_init.cc [new file with mode: 0644]

index c9bac6cfb18bfea363eff5bfc225bcf0cf2de395..1867270701467b3ab694ca3fbb4836aaee6d91f3 100644 (file)
@@ -1,3 +1,15 @@
+2001-06-05  Benjamin Kosnik  <bkoz@redhat.com>
+
+       libstdc++/3045
+       * include/bits/basic_ios.tcc: Formatting tweaks.
+       * include/bits/ios_base.h: Formatting tweaks.
+       * src/ios.cc (ios_base::Init::_S_ios_create): Use filebufs here.
+       (ios_base::Init::_S_ios_destroy): ..and here. Explicitly call dtors.
+       * src/globals.cc: Allocate filebufs for standard streams here.
+       (buf_cout, buf_cin, buf_cerr): Like so.
+       (buf_wcout, buf_wcin, buf_wcerr): And so.
+       * testsuite/27_io/ios_init.cc: Add.
+       
 2001-06-04  Brendan Kehoe  <brendan@zen.org>
            Benjamin Kosnik  <bkoz@redhat.com>
        
index 6a3db778c20d2235f84b8149ca5a385c012e280b..47d940bd69cb7afbd0c73b52b9a0c9b71b86ad0f 100644 (file)
@@ -30,8 +30,8 @@
 #ifndef _CPP_BITS_BASICIOS_TCC
 #define _CPP_BITS_BASICIOS_TCC 1
 
-namespace std {
-
+namespace std
+{
   template<typename _CharT, typename _Traits>
     basic_streambuf<_CharT, _Traits>* 
     basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb)
index 31b8d3a917d351667decf67debed7d3640b4120f..381e1cb00d785869af3f20b15cf302cdfe872eac 100644 (file)
@@ -38,7 +38,6 @@
 
 namespace std
 {
-
   // The following definitions of bitmask types are enums, not ints,
   // as permitted (but not required) in the standard, in order to provide
   // better type safety in iostream calls.  A side effect is that
index bd24d8fa00dc17d0e8dcfc9cf5685cde6961a6cb..11930b0083440f3edf88125eba48b72b8ccd633e 100644 (file)
 // invalidate any other reasons why the executable file might be covered by
 // the GNU General Public License.
 
-// On AIX, and perhaps other systems, library initialization order
-// is not guaranteed.  For example, the static initializers for the 
-// main program might run before the static initializers for this
-// library.  That means that we cannot rely on static initialization in 
-// the library; there is no guarantee that things will get initialized
-// in time.  This file contains definitions of all global variables
-// that require initialization as arrays of characters.
-
+#include <fstream>
 #include <istream>
 #include <ostream>
 
-namespace std {
-  typedef char fake_istream[sizeof (istream)] 
-  __attribute__ ((aligned (__alignof__ (istream))));
-  typedef char fake_ostream[sizeof (ostream)] 
-  __attribute__ ((aligned (__alignof__ (ostream))));
+// On AIX, and perhaps other systems, library initialization order is
+// not guaranteed.  For example, the static initializers for the main
+// program might run before the static initializers for this library.
+// That means that we cannot rely on static initialization in the
+// library; there is no guarantee that things will get initialized in
+// time.  This file contains definitions of all global variables that
+// require initialization as arrays of characters.
 
+// Because <iostream> declares the standard streams to be [io]stream
+// types instead of say [io]fstream types, it is also necessary to
+// allocate the actual file buffers in this file.
+namespace std 
+{
+  typedef char fake_istream[sizeof(istream)]
+  __attribute__ ((aligned(__alignof__(istream))));
+  typedef char fake_ostream[sizeof(ostream)] 
+  __attribute__ ((aligned(__alignof__(ostream))));
   fake_istream cin;
   fake_ostream cout;
   fake_ostream cerr;
   fake_ostream clog;
 
-#ifdef _GLIBCPP_USE_WCHAR_T
-  typedef char fake_wistream[sizeof (wistream)] 
-  __attribute__ ((aligned (__alignof__ (wistream))));
-  typedef char fake_wostream[sizeof (wostream)] 
-  __attribute__ ((aligned (__alignof__ (wostream))));
+  typedef char fake_filebuf[sizeof(filebuf)]
+  __attribute__ ((aligned(__alignof__(filebuf))));
+  fake_filebuf buf_cout;
+  fake_filebuf buf_cin;
+  fake_filebuf buf_cerr;
 
+#ifdef _GLIBCPP_USE_WCHAR_T
+  typedef char fake_wistream[sizeof(wistream)] 
+  __attribute__ ((aligned(__alignof__(wistream))));
+  typedef char fake_wostream[sizeof(wostream)] 
+  __attribute__ ((aligned(__alignof__(wostream))));
   fake_wistream wcin;
   fake_wostream wcout;
   fake_wostream wcerr;
   fake_wostream wclog;
+
+  typedef char fake_wfilebuf[sizeof(wfilebuf)]
+  __attribute__ ((aligned(__alignof__(wfilebuf))));
+  fake_wfilebuf buf_wcout;
+  fake_wfilebuf buf_wcin;
+  fake_wfilebuf buf_wcerr;
 #endif
 }
index 6d4039d7ec47f3c7b740b3f34c6d2442eb1a9535..244585e98849eb84ffd90c8a2ea030133a82fe59 100644 (file)
 
 namespace std 
 {
+  // Extern declarations for global objects in src/globals.cc.
+  extern istream cin;
+  extern ostream cout;
+  extern ostream cerr;
+  extern ostream clog;
+  extern filebuf buf_cout;
+  extern filebuf buf_cin;
+  extern filebuf buf_cerr;
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+  extern wistream wcin;
+  extern wostream wcout;
+  extern wostream wcerr;
+  extern wostream wclog;
+  extern wfilebuf buf_wcout;
+  extern wfilebuf buf_wcin;
+  extern wfilebuf buf_wcerr;
+#endif
+
   // Definitions for static const data members of __ios_flags.
   const __ios_flags::__int_type __ios_flags::_S_boolalpha;
   const __ios_flags::__int_type __ios_flags::_S_dec;
@@ -109,17 +128,6 @@ namespace std
   int ios_base::Init::_S_ios_base_init = 0;
   bool ios_base::Init::_S_synced_with_stdio = true;
 
-  extern istream cin;
-  extern ostream cout;
-  extern ostream cerr;
-  extern ostream clog;
-#ifdef _GLIBCPP_USE_WCHAR_T
-  extern wistream wcin;
-  extern wostream wcout;
-  extern wostream wcerr;
-  extern wostream wclog;
-#endif
-
   ios_base::failure::failure(const string& __str) throw()
   {
     strncpy(_M_name, __str.c_str(), _M_bufsize);
@@ -137,55 +145,65 @@ namespace std
   ios_base::Init::_S_ios_create(bool __sync)
   {
     int __bufsize = __sync ? 0 : static_cast<int>(BUFSIZ);
-    // NB: The file std_iostream.h creates the four standard files
+
+    // NB: The file globals.cc creates the four standard files
     // with NULL buffers. At this point, we swap out the dummy NULL
-    // buffers with the real deal.
-    new (&cout) ostream(new filebuf(stdout, ios_base::out, __bufsize));
-    new (&cin) istream(new filebuf(stdin, ios_base::in, 1));
-    new (&cerr) ostream(new filebuf(stderr, ios_base::out, __bufsize));
-    new (&clog) ostream(cerr.rdbuf());
+    // [io]stream objects and buffers with the real deal.
+    new (&buf_cout) filebuf(stdout, ios_base::out, __bufsize);
+    new (&buf_cin) filebuf(stdin, ios_base::in, 1);
+    new (&buf_cerr) filebuf(stderr, ios_base::out, __bufsize);
+    new (&cout) ostream(&buf_cout);
+    new (&cin) istream(&buf_cin);
+    new (&cerr) ostream(&buf_cerr);
+    new (&clog) ostream(&buf_cerr);
     cin.tie(&cout);
     cerr.flags(ios_base::unitbuf);
     
 #ifdef _GLIBCPP_USE_WCHAR_T
-    new (&wcout) wostream( new wfilebuf(stdout, ios_base::out, __bufsize));
-    new (&wcin) wistream(new wfilebuf(stdin, ios_base::in, 1));
-    new (&wcerr) wostream(new wfilebuf(stderr, ios_base::out, __bufsize));
-    new (&wclog) wostream(wcerr.rdbuf());
+    new (&buf_wcout) wfilebuf(stdout, ios_base::out, __bufsize);
+    new (&buf_wcin) wfilebuf(stdin, ios_base::in, 1);
+    new (&buf_wcerr) wfilebuf(stderr, ios_base::out, __bufsize);
+    new (&wcout) wostream(&buf_wcout);
+    new (&wcin) wistream(&buf_wcin);
+    new (&wcerr) wostream(&buf_wcerr);
+    new (&wclog) wostream(&buf_wcerr);
     wcin.tie(&wcout);
     wcerr.flags(ios_base::unitbuf);
 #endif
   }
 
-  ios_base::Init::Init()
-  {
-    if (++_S_ios_base_init == 1)
-      {
-       // Standard streams default to synced with "C" operations.
-       ios_base::Init::_S_synced_with_stdio = true;
-       _S_ios_create(ios_base::Init::_S_synced_with_stdio);
-      }
-  }
-
   void
   ios_base::Init::_S_ios_destroy()
   {
+    // Explicitly call dtors to free any memory that is dynamically
+    // allocated by filebuf ctor or member functions, but don't
+    // deallocate all memory by calling operator delete.
     cout.flush();
     cerr.flush();
     clog.flush();
-    delete cout.rdbuf();
-    delete cin.rdbuf();
-    delete cerr.rdbuf();
+    buf_cout.~filebuf();
+    buf_cin.~filebuf();
+    buf_cerr.~filebuf();
 #ifdef _GLIBCPP_USE_WCHAR_T
     wcout.flush();
     wcerr.flush();
     wclog.flush();
-    delete wcout.rdbuf();
-    delete wcin.rdbuf();
-    delete wcerr.rdbuf();
+    buf_wcout.~wfilebuf();
+    buf_wcin.~wfilebuf();
+    buf_wcerr.~wfilebuf();
 #endif
   }
 
+  ios_base::Init::Init()
+  {
+    if (++_S_ios_base_init == 1)
+      {
+       // Standard streams default to synced with "C" operations.
+       ios_base::Init::_S_synced_with_stdio = true;
+       _S_ios_create(ios_base::Init::_S_synced_with_stdio);
+      }
+  }
+
   ios_base::Init::~Init()
   {
     if (--_S_ios_base_init == 0)
diff --git a/libstdc++-v3/testsuite/27_io/ios_init.cc b/libstdc++-v3/testsuite/27_io/ios_init.cc
new file mode 100644 (file)
index 0000000..3963cb6
--- /dev/null
@@ -0,0 +1,88 @@
+// 2001-06-05 Benjamin Kosnik  <bkoz@redhat.com>
+
+// Copyright (C) 2001 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.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// 27.4.2.1.6 class ios_base::init
+
+#include <fstream>
+#include <iostream>
+#include <debug_assert.h>
+
+class gnu_filebuf: public std::filebuf
+{
+  int i;
+public:
+  gnu_filebuf(int j = 1): i(j) { }
+  ~gnu_filebuf() { --i; }
+  int get_i() { return i;}
+};
+
+const int initial = 4;
+gnu_filebuf buf(initial);
+
+// libstdc++/3045, in a vague way.
+void test01()
+{
+  bool test = true;
+  int k1;
+
+  // 1 normal
+  k1 = buf.get_i();
+  VERIFY( k1 == initial );
+  {
+    std::cout.rdbuf(&buf);
+  }
+  k1 = buf.get_i();
+  VERIFY( k1 == initial );
+
+  // 2 syncd off
+  k1 = buf.get_i();
+  VERIFY( k1 == initial );
+  {
+    std::cout.rdbuf(&buf);
+    std::ios_base::sync_with_stdio(false); // make sure doesn't clobber buf
+  }
+  k1 = buf.get_i();
+  VERIFY( k1 == initial );
+
+  // 3 callling init
+  k1 = buf.get_i();
+  VERIFY( k1 == initial );
+  {
+    std::cout.rdbuf(&buf);
+    std::ios_base::Init make_sure_initialized;
+  }
+  k1 = buf.get_i();
+  VERIFY( k1 == initial );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}