xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/src/c++98/ios_init.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
148fb7bfaSmrg // Iostreams base classes -*- C++ -*-
248fb7bfaSmrg 
3*b1e83836Smrg // Copyright (C) 1997-2022 Free Software Foundation, Inc.
448fb7bfaSmrg //
548fb7bfaSmrg // This file is part of the GNU ISO C++ Library.  This library is free
648fb7bfaSmrg // software; you can redistribute it and/or modify it under the
748fb7bfaSmrg // terms of the GNU General Public License as published by the
848fb7bfaSmrg // Free Software Foundation; either version 3, or (at your option)
948fb7bfaSmrg // any later version.
1048fb7bfaSmrg 
1148fb7bfaSmrg // This library is distributed in the hope that it will be useful,
1248fb7bfaSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
1348fb7bfaSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1448fb7bfaSmrg // GNU General Public License for more details.
1548fb7bfaSmrg 
1648fb7bfaSmrg // Under Section 7 of GPL version 3, you are granted additional
1748fb7bfaSmrg // permissions described in the GCC Runtime Library Exception, version
1848fb7bfaSmrg // 3.1, as published by the Free Software Foundation.
1948fb7bfaSmrg 
2048fb7bfaSmrg // You should have received a copy of the GNU General Public License and
2148fb7bfaSmrg // a copy of the GCC Runtime Library Exception along with this program;
2248fb7bfaSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2348fb7bfaSmrg // <http://www.gnu.org/licenses/>.
2448fb7bfaSmrg 
2548fb7bfaSmrg //
2648fb7bfaSmrg // ISO C++ 14882: 27.4  Iostreams base classes
2748fb7bfaSmrg //
2848fb7bfaSmrg 
2948fb7bfaSmrg #include <ios>
3048fb7bfaSmrg #include <ostream>
3148fb7bfaSmrg #include <istream>
3248fb7bfaSmrg #include <fstream>
3348fb7bfaSmrg #include <ext/stdio_filebuf.h>
3448fb7bfaSmrg #include <ext/stdio_sync_filebuf.h>
3548fb7bfaSmrg 
3648fb7bfaSmrg namespace __gnu_internal _GLIBCXX_VISIBILITY(hidden)
3748fb7bfaSmrg {
3848fb7bfaSmrg   using namespace __gnu_cxx;
3948fb7bfaSmrg 
405f4cdc7dSskrll   // Extern declarations for global objects in src/c++98/globals.cc.
4148fb7bfaSmrg   extern stdio_sync_filebuf<char> buf_cout_sync;
4248fb7bfaSmrg   extern stdio_sync_filebuf<char> buf_cin_sync;
4348fb7bfaSmrg   extern stdio_sync_filebuf<char> buf_cerr_sync;
4448fb7bfaSmrg 
4548fb7bfaSmrg   extern stdio_filebuf<char> buf_cout;
4648fb7bfaSmrg   extern stdio_filebuf<char> buf_cin;
4748fb7bfaSmrg   extern stdio_filebuf<char> buf_cerr;
4848fb7bfaSmrg 
4948fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T
5048fb7bfaSmrg   extern stdio_sync_filebuf<wchar_t> buf_wcout_sync;
5148fb7bfaSmrg   extern stdio_sync_filebuf<wchar_t> buf_wcin_sync;
5248fb7bfaSmrg   extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync;
5348fb7bfaSmrg 
5448fb7bfaSmrg   extern stdio_filebuf<wchar_t> buf_wcout;
5548fb7bfaSmrg   extern stdio_filebuf<wchar_t> buf_wcin;
5648fb7bfaSmrg   extern stdio_filebuf<wchar_t> buf_wcerr;
5748fb7bfaSmrg #endif
5848fb7bfaSmrg } // namespace __gnu_internal
5948fb7bfaSmrg 
6048fb7bfaSmrg namespace std _GLIBCXX_VISIBILITY(default)
6148fb7bfaSmrg {
6248fb7bfaSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
6348fb7bfaSmrg 
6448fb7bfaSmrg   using namespace __gnu_internal;
6548fb7bfaSmrg 
6648fb7bfaSmrg   extern istream cin;
6748fb7bfaSmrg   extern ostream cout;
6848fb7bfaSmrg   extern ostream cerr;
6948fb7bfaSmrg   extern ostream clog;
7048fb7bfaSmrg 
7148fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T
7248fb7bfaSmrg   extern wistream wcin;
7348fb7bfaSmrg   extern wostream wcout;
7448fb7bfaSmrg   extern wostream wcerr;
7548fb7bfaSmrg   extern wostream wclog;
7648fb7bfaSmrg #endif
7748fb7bfaSmrg 
Init()7848fb7bfaSmrg   ios_base::Init::Init()
7948fb7bfaSmrg   {
8048fb7bfaSmrg     if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, 1) == 0)
8148fb7bfaSmrg       {
8248fb7bfaSmrg 	// Standard streams default to synced with "C" operations.
8348fb7bfaSmrg 	_S_synced_with_stdio = true;
8448fb7bfaSmrg 
8548fb7bfaSmrg 	new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout);
8648fb7bfaSmrg 	new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin);
8748fb7bfaSmrg 	new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr);
8848fb7bfaSmrg 
8948fb7bfaSmrg 	// The standard streams are constructed once only and never
9048fb7bfaSmrg 	// destroyed.
9148fb7bfaSmrg 	new (&cout) ostream(&buf_cout_sync);
9248fb7bfaSmrg 	new (&cin) istream(&buf_cin_sync);
9348fb7bfaSmrg 	new (&cerr) ostream(&buf_cerr_sync);
9448fb7bfaSmrg 	new (&clog) ostream(&buf_cerr_sync);
9548fb7bfaSmrg 	cin.tie(&cout);
9648fb7bfaSmrg 	cerr.setf(ios_base::unitbuf);
9748fb7bfaSmrg 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
9848fb7bfaSmrg 	// 455. cerr::tie() and wcerr::tie() are overspecified.
9948fb7bfaSmrg 	cerr.tie(&cout);
10048fb7bfaSmrg 
10148fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T
10248fb7bfaSmrg 	new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout);
10348fb7bfaSmrg 	new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin);
10448fb7bfaSmrg 	new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr);
10548fb7bfaSmrg 
10648fb7bfaSmrg 	new (&wcout) wostream(&buf_wcout_sync);
10748fb7bfaSmrg 	new (&wcin) wistream(&buf_wcin_sync);
10848fb7bfaSmrg 	new (&wcerr) wostream(&buf_wcerr_sync);
10948fb7bfaSmrg 	new (&wclog) wostream(&buf_wcerr_sync);
11048fb7bfaSmrg 	wcin.tie(&wcout);
11148fb7bfaSmrg 	wcerr.setf(ios_base::unitbuf);
11248fb7bfaSmrg 	wcerr.tie(&wcout);
11348fb7bfaSmrg #endif
11448fb7bfaSmrg 
11548fb7bfaSmrg 	// NB: Have to set refcount above one, so that standard
11648fb7bfaSmrg 	// streams are not re-initialized with uses of ios_base::Init
11748fb7bfaSmrg 	// besides <iostream> static object, ie just using <ios> with
11848fb7bfaSmrg 	// ios_base::Init objects.
11948fb7bfaSmrg 	__gnu_cxx::__atomic_add_dispatch(&_S_refcount, 1);
12048fb7bfaSmrg       }
12148fb7bfaSmrg   }
12248fb7bfaSmrg 
~Init()12348fb7bfaSmrg   ios_base::Init::~Init()
12448fb7bfaSmrg   {
12548fb7bfaSmrg     // Be race-detector-friendly.  For more info see bits/c++config.
12648fb7bfaSmrg     _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_S_refcount);
12748fb7bfaSmrg     if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, -1) == 2)
12848fb7bfaSmrg       {
12948fb7bfaSmrg         _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_S_refcount);
13048fb7bfaSmrg 	// Catch any exceptions thrown by basic_ostream::flush()
13148fb7bfaSmrg 	__try
13248fb7bfaSmrg 	  {
13348fb7bfaSmrg 	    // Flush standard output streams as required by 27.4.2.1.6
13448fb7bfaSmrg 	    cout.flush();
13548fb7bfaSmrg 	    cerr.flush();
13648fb7bfaSmrg 	    clog.flush();
13748fb7bfaSmrg 
13848fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T
13948fb7bfaSmrg 	    wcout.flush();
14048fb7bfaSmrg 	    wcerr.flush();
14148fb7bfaSmrg 	    wclog.flush();
14248fb7bfaSmrg #endif
14348fb7bfaSmrg 	  }
14448fb7bfaSmrg 	__catch(...)
14548fb7bfaSmrg 	  { }
14648fb7bfaSmrg       }
14748fb7bfaSmrg   }
14848fb7bfaSmrg 
14948fb7bfaSmrg   bool
sync_with_stdio(bool __sync)15048fb7bfaSmrg   ios_base::sync_with_stdio(bool __sync)
15148fb7bfaSmrg   {
15248fb7bfaSmrg     // _GLIBCXX_RESOLVE_LIB_DEFECTS
15348fb7bfaSmrg     // 49.  Underspecification of ios_base::sync_with_stdio
15448fb7bfaSmrg     bool __ret = ios_base::Init::_S_synced_with_stdio;
15548fb7bfaSmrg 
15648fb7bfaSmrg     // Turn off sync with C FILE* for cin, cout, cerr, clog iff
15748fb7bfaSmrg     // currently synchronized.
15848fb7bfaSmrg     if (!__sync && __ret)
15948fb7bfaSmrg       {
16048fb7bfaSmrg 	// Make sure the standard streams are constructed.
16148fb7bfaSmrg 	ios_base::Init __init;
16248fb7bfaSmrg 
16348fb7bfaSmrg 	ios_base::Init::_S_synced_with_stdio = __sync;
16448fb7bfaSmrg 
16548fb7bfaSmrg 	// Explicitly call dtors to free any memory that is
16648fb7bfaSmrg 	// dynamically allocated by filebuf ctor or member functions,
16748fb7bfaSmrg 	// but don't deallocate all memory by calling operator delete.
16848fb7bfaSmrg 	buf_cout_sync.~stdio_sync_filebuf<char>();
16948fb7bfaSmrg 	buf_cin_sync.~stdio_sync_filebuf<char>();
17048fb7bfaSmrg 	buf_cerr_sync.~stdio_sync_filebuf<char>();
17148fb7bfaSmrg 
17248fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T
17348fb7bfaSmrg 	buf_wcout_sync.~stdio_sync_filebuf<wchar_t>();
17448fb7bfaSmrg 	buf_wcin_sync.~stdio_sync_filebuf<wchar_t>();
17548fb7bfaSmrg 	buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>();
17648fb7bfaSmrg #endif
17748fb7bfaSmrg 
17848fb7bfaSmrg 	// Create stream buffers for the standard streams and use
17948fb7bfaSmrg 	// those buffers without destroying and recreating the
18048fb7bfaSmrg 	// streams.
18148fb7bfaSmrg 	new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out);
18248fb7bfaSmrg 	new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in);
18348fb7bfaSmrg 	new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out);
18448fb7bfaSmrg 	cout.rdbuf(&buf_cout);
18548fb7bfaSmrg 	cin.rdbuf(&buf_cin);
18648fb7bfaSmrg 	cerr.rdbuf(&buf_cerr);
18748fb7bfaSmrg 	clog.rdbuf(&buf_cerr);
18848fb7bfaSmrg 
18948fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T
19048fb7bfaSmrg 	new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out);
19148fb7bfaSmrg 	new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in);
19248fb7bfaSmrg 	new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out);
19348fb7bfaSmrg 	wcout.rdbuf(&buf_wcout);
19448fb7bfaSmrg 	wcin.rdbuf(&buf_wcin);
19548fb7bfaSmrg 	wcerr.rdbuf(&buf_wcerr);
19648fb7bfaSmrg 	wclog.rdbuf(&buf_wcerr);
19748fb7bfaSmrg #endif
19848fb7bfaSmrg       }
19948fb7bfaSmrg     return __ret;
20048fb7bfaSmrg   }
20148fb7bfaSmrg 
20248fb7bfaSmrg _GLIBCXX_END_NAMESPACE_VERSION
20348fb7bfaSmrg } // namespace
204