xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/src/c++98/ios_init.cc (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
136ac495dSmrg // Iostreams base classes -*- C++ -*-
236ac495dSmrg 
3*8feb0f0bSmrg // Copyright (C) 1997-2020 Free Software Foundation, Inc.
436ac495dSmrg //
536ac495dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
636ac495dSmrg // software; you can redistribute it and/or modify it under the
736ac495dSmrg // terms of the GNU General Public License as published by the
836ac495dSmrg // Free Software Foundation; either version 3, or (at your option)
936ac495dSmrg // any later version.
1036ac495dSmrg 
1136ac495dSmrg // This library is distributed in the hope that it will be useful,
1236ac495dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
1336ac495dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1436ac495dSmrg // GNU General Public License for more details.
1536ac495dSmrg 
1636ac495dSmrg // Under Section 7 of GPL version 3, you are granted additional
1736ac495dSmrg // permissions described in the GCC Runtime Library Exception, version
1836ac495dSmrg // 3.1, as published by the Free Software Foundation.
1936ac495dSmrg 
2036ac495dSmrg // You should have received a copy of the GNU General Public License and
2136ac495dSmrg // a copy of the GCC Runtime Library Exception along with this program;
2236ac495dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2336ac495dSmrg // <http://www.gnu.org/licenses/>.
2436ac495dSmrg 
2536ac495dSmrg //
2636ac495dSmrg // ISO C++ 14882: 27.4  Iostreams base classes
2736ac495dSmrg //
2836ac495dSmrg 
2936ac495dSmrg #include <ios>
3036ac495dSmrg #include <ostream>
3136ac495dSmrg #include <istream>
3236ac495dSmrg #include <fstream>
3336ac495dSmrg #include <ext/stdio_filebuf.h>
3436ac495dSmrg #include <ext/stdio_sync_filebuf.h>
3536ac495dSmrg 
3636ac495dSmrg namespace __gnu_internal _GLIBCXX_VISIBILITY(hidden)
3736ac495dSmrg {
3836ac495dSmrg   using namespace __gnu_cxx;
3936ac495dSmrg 
4036ac495dSmrg   // Extern declarations for global objects in src/c++98/globals.cc.
4136ac495dSmrg   extern stdio_sync_filebuf<char> buf_cout_sync;
4236ac495dSmrg   extern stdio_sync_filebuf<char> buf_cin_sync;
4336ac495dSmrg   extern stdio_sync_filebuf<char> buf_cerr_sync;
4436ac495dSmrg 
4536ac495dSmrg   extern stdio_filebuf<char> buf_cout;
4636ac495dSmrg   extern stdio_filebuf<char> buf_cin;
4736ac495dSmrg   extern stdio_filebuf<char> buf_cerr;
4836ac495dSmrg 
4936ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T
5036ac495dSmrg   extern stdio_sync_filebuf<wchar_t> buf_wcout_sync;
5136ac495dSmrg   extern stdio_sync_filebuf<wchar_t> buf_wcin_sync;
5236ac495dSmrg   extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync;
5336ac495dSmrg 
5436ac495dSmrg   extern stdio_filebuf<wchar_t> buf_wcout;
5536ac495dSmrg   extern stdio_filebuf<wchar_t> buf_wcin;
5636ac495dSmrg   extern stdio_filebuf<wchar_t> buf_wcerr;
5736ac495dSmrg #endif
5836ac495dSmrg } // namespace __gnu_internal
5936ac495dSmrg 
6036ac495dSmrg namespace std _GLIBCXX_VISIBILITY(default)
6136ac495dSmrg {
6236ac495dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
6336ac495dSmrg 
6436ac495dSmrg   using namespace __gnu_internal;
6536ac495dSmrg 
6636ac495dSmrg   extern istream cin;
6736ac495dSmrg   extern ostream cout;
6836ac495dSmrg   extern ostream cerr;
6936ac495dSmrg   extern ostream clog;
7036ac495dSmrg 
7136ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T
7236ac495dSmrg   extern wistream wcin;
7336ac495dSmrg   extern wostream wcout;
7436ac495dSmrg   extern wostream wcerr;
7536ac495dSmrg   extern wostream wclog;
7636ac495dSmrg #endif
7736ac495dSmrg 
Init()7836ac495dSmrg   ios_base::Init::Init()
7936ac495dSmrg   {
8036ac495dSmrg     if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, 1) == 0)
8136ac495dSmrg       {
8236ac495dSmrg 	// Standard streams default to synced with "C" operations.
8336ac495dSmrg 	_S_synced_with_stdio = true;
8436ac495dSmrg 
8536ac495dSmrg 	new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout);
8636ac495dSmrg 	new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin);
8736ac495dSmrg 	new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr);
8836ac495dSmrg 
8936ac495dSmrg 	// The standard streams are constructed once only and never
9036ac495dSmrg 	// destroyed.
9136ac495dSmrg 	new (&cout) ostream(&buf_cout_sync);
9236ac495dSmrg 	new (&cin) istream(&buf_cin_sync);
9336ac495dSmrg 	new (&cerr) ostream(&buf_cerr_sync);
9436ac495dSmrg 	new (&clog) ostream(&buf_cerr_sync);
9536ac495dSmrg 	cin.tie(&cout);
9636ac495dSmrg 	cerr.setf(ios_base::unitbuf);
9736ac495dSmrg 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
9836ac495dSmrg 	// 455. cerr::tie() and wcerr::tie() are overspecified.
9936ac495dSmrg 	cerr.tie(&cout);
10036ac495dSmrg 
10136ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T
10236ac495dSmrg 	new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout);
10336ac495dSmrg 	new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin);
10436ac495dSmrg 	new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr);
10536ac495dSmrg 
10636ac495dSmrg 	new (&wcout) wostream(&buf_wcout_sync);
10736ac495dSmrg 	new (&wcin) wistream(&buf_wcin_sync);
10836ac495dSmrg 	new (&wcerr) wostream(&buf_wcerr_sync);
10936ac495dSmrg 	new (&wclog) wostream(&buf_wcerr_sync);
11036ac495dSmrg 	wcin.tie(&wcout);
11136ac495dSmrg 	wcerr.setf(ios_base::unitbuf);
11236ac495dSmrg 	wcerr.tie(&wcout);
11336ac495dSmrg #endif
11436ac495dSmrg 
11536ac495dSmrg 	// NB: Have to set refcount above one, so that standard
11636ac495dSmrg 	// streams are not re-initialized with uses of ios_base::Init
11736ac495dSmrg 	// besides <iostream> static object, ie just using <ios> with
11836ac495dSmrg 	// ios_base::Init objects.
11936ac495dSmrg 	__gnu_cxx::__atomic_add_dispatch(&_S_refcount, 1);
12036ac495dSmrg       }
12136ac495dSmrg   }
12236ac495dSmrg 
~Init()12336ac495dSmrg   ios_base::Init::~Init()
12436ac495dSmrg   {
12536ac495dSmrg     // Be race-detector-friendly.  For more info see bits/c++config.
12636ac495dSmrg     _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_S_refcount);
12736ac495dSmrg     if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, -1) == 2)
12836ac495dSmrg       {
12936ac495dSmrg         _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_S_refcount);
13036ac495dSmrg 	// Catch any exceptions thrown by basic_ostream::flush()
13136ac495dSmrg 	__try
13236ac495dSmrg 	  {
13336ac495dSmrg 	    // Flush standard output streams as required by 27.4.2.1.6
13436ac495dSmrg 	    cout.flush();
13536ac495dSmrg 	    cerr.flush();
13636ac495dSmrg 	    clog.flush();
13736ac495dSmrg 
13836ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T
13936ac495dSmrg 	    wcout.flush();
14036ac495dSmrg 	    wcerr.flush();
14136ac495dSmrg 	    wclog.flush();
14236ac495dSmrg #endif
14336ac495dSmrg 	  }
14436ac495dSmrg 	__catch(...)
14536ac495dSmrg 	  { }
14636ac495dSmrg       }
14736ac495dSmrg   }
14836ac495dSmrg 
14936ac495dSmrg   bool
sync_with_stdio(bool __sync)15036ac495dSmrg   ios_base::sync_with_stdio(bool __sync)
15136ac495dSmrg   {
15236ac495dSmrg     // _GLIBCXX_RESOLVE_LIB_DEFECTS
15336ac495dSmrg     // 49.  Underspecification of ios_base::sync_with_stdio
15436ac495dSmrg     bool __ret = ios_base::Init::_S_synced_with_stdio;
15536ac495dSmrg 
15636ac495dSmrg     // Turn off sync with C FILE* for cin, cout, cerr, clog iff
15736ac495dSmrg     // currently synchronized.
15836ac495dSmrg     if (!__sync && __ret)
15936ac495dSmrg       {
16036ac495dSmrg 	// Make sure the standard streams are constructed.
16136ac495dSmrg 	ios_base::Init __init;
16236ac495dSmrg 
16336ac495dSmrg 	ios_base::Init::_S_synced_with_stdio = __sync;
16436ac495dSmrg 
16536ac495dSmrg 	// Explicitly call dtors to free any memory that is
16636ac495dSmrg 	// dynamically allocated by filebuf ctor or member functions,
16736ac495dSmrg 	// but don't deallocate all memory by calling operator delete.
16836ac495dSmrg 	buf_cout_sync.~stdio_sync_filebuf<char>();
16936ac495dSmrg 	buf_cin_sync.~stdio_sync_filebuf<char>();
17036ac495dSmrg 	buf_cerr_sync.~stdio_sync_filebuf<char>();
17136ac495dSmrg 
17236ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T
17336ac495dSmrg 	buf_wcout_sync.~stdio_sync_filebuf<wchar_t>();
17436ac495dSmrg 	buf_wcin_sync.~stdio_sync_filebuf<wchar_t>();
17536ac495dSmrg 	buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>();
17636ac495dSmrg #endif
17736ac495dSmrg 
17836ac495dSmrg 	// Create stream buffers for the standard streams and use
17936ac495dSmrg 	// those buffers without destroying and recreating the
18036ac495dSmrg 	// streams.
18136ac495dSmrg 	new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out);
18236ac495dSmrg 	new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in);
18336ac495dSmrg 	new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out);
18436ac495dSmrg 	cout.rdbuf(&buf_cout);
18536ac495dSmrg 	cin.rdbuf(&buf_cin);
18636ac495dSmrg 	cerr.rdbuf(&buf_cerr);
18736ac495dSmrg 	clog.rdbuf(&buf_cerr);
18836ac495dSmrg 
18936ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T
19036ac495dSmrg 	new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out);
19136ac495dSmrg 	new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in);
19236ac495dSmrg 	new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out);
19336ac495dSmrg 	wcout.rdbuf(&buf_wcout);
19436ac495dSmrg 	wcin.rdbuf(&buf_wcin);
19536ac495dSmrg 	wcerr.rdbuf(&buf_wcerr);
19636ac495dSmrg 	wclog.rdbuf(&buf_wcerr);
19736ac495dSmrg #endif
19836ac495dSmrg       }
19936ac495dSmrg     return __ret;
20036ac495dSmrg   }
20136ac495dSmrg 
20236ac495dSmrg _GLIBCXX_END_NAMESPACE_VERSION
20336ac495dSmrg } // namespace
204