diff options
author | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-06-06 01:31:58 +0000 |
---|---|---|
committer | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-06-06 01:31:58 +0000 |
commit | a3eef8655ec7fb776ab66f283b26e3e2d2dbd402 (patch) | |
tree | 9a6f2713e4cae48b2272089a4ed08a4746d26a98 /libstdc++-v3 | |
parent | db87fabf9db475224b4fae540288c0dc500dac68 (diff) | |
download | gcc-a3eef8655ec7fb776ab66f283b26e3e2d2dbd402.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@42922 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/basic_ios.tcc | 4 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/ios_base.h | 1 | ||||
-rw-r--r-- | libstdc++-v3/src/globals.cc | 51 | ||||
-rw-r--r-- | libstdc++-v3/src/ios.cc | 92 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/ios_init.cc | 88 |
6 files changed, 190 insertions, 58 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c9bac6cfb18..18672707014 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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> diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc index 6a3db778c20..47d940bd69c 100644 --- a/libstdc++-v3/include/bits/basic_ios.tcc +++ b/libstdc++-v3/include/bits/basic_ios.tcc @@ -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) diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h index 31b8d3a917d..381e1cb00d7 100644 --- a/libstdc++-v3/include/bits/ios_base.h +++ b/libstdc++-v3/include/bits/ios_base.h @@ -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 diff --git a/libstdc++-v3/src/globals.cc b/libstdc++-v3/src/globals.cc index bd24d8fa00d..11930b00834 100644 --- a/libstdc++-v3/src/globals.cc +++ b/libstdc++-v3/src/globals.cc @@ -25,37 +25,52 @@ // 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 } diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc index 6d4039d7ec4..244585e9884 100644 --- a/libstdc++-v3/src/ios.cc +++ b/libstdc++-v3/src/ios.cc @@ -38,6 +38,25 @@ 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 index 00000000000..3963cb6d776 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/ios_init.cc @@ -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; +} |