# ios_init.cc

    00001 // Iostreams base classes -*- C++ -*-
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    00004 // Free Software Foundation, Inc.
    00005 //
    00006 // This file is part of the GNU ISO C++ Library.  This library is free
    00007 // software; you can redistribute it and/or modify it under the
    00008 // terms of the GNU General Public License as published by the
    00009 // Free Software Foundation; either version 2, or (at your option)
    00010 // any later version.
    00011
    00012 // This library is distributed in the hope that it will be useful,
    00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00015 // GNU General Public License for more details.
    00016
    00017 // You should have received a copy of the GNU General Public License along
    00018 // with this library; see the file COPYING.  If not, write to the Free
    00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
    00020 // USA.
    00021
    00022 // As a special exception, you may use this file as part of a free software
    00023 // library without restriction.  Specifically, if other files instantiate
    00024 // templates or use macros or inline functions from this file, or you compile
    00025 // this file and link it with other files to produce an executable, this
    00026 // file does not by itself cause the resulting executable to be covered by
    00027 // the GNU General Public License.  This exception does not however
    00028 // invalidate any other reasons why the executable file might be covered by
    00029 // the GNU General Public License.
    00030
    00031 //
    00032 // ISO C++ 14882: 27.4  Iostreams base classes
    00033 //
    00034
    00035 #include <ios>
    00036 #include <ostream>
    00037 #include <istream>
    00038 #include <fstream>
    00039 #include <bits/atomicity.h>
    00040 #include <ext/stdio_filebuf.h>
    00041 #include <ext/stdio_sync_filebuf.h>
    00042
    00043 namespace __gnu_internal
    00044 {
    00045   using namespace __gnu_cxx;
    00046
    00047   // Extern declarations for global objects in src/globals.cc.
    00048   extern stdio_sync_filebuf<char> buf_cout_sync;
    00049   extern stdio_sync_filebuf<char> buf_cin_sync;
    00050   extern stdio_sync_filebuf<char> buf_cerr_sync;
    00051
    00052   extern stdio_filebuf<char> buf_cout;
    00053   extern stdio_filebuf<char> buf_cin;
    00054   extern stdio_filebuf<char> buf_cerr;
    00055
    00056 #ifdef _GLIBCXX_USE_WCHAR_T
    00057   extern stdio_sync_filebuf<wchar_t> buf_wcout_sync;
    00058   extern stdio_sync_filebuf<wchar_t> buf_wcin_sync;
    00059   extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync;
    00060
    00061   extern stdio_filebuf<wchar_t> buf_wcout;
    00062   extern stdio_filebuf<wchar_t> buf_wcin;
    00063   extern stdio_filebuf<wchar_t> buf_wcerr;
    00064 #endif
    00065 } // namespace __gnu_internal
    00066
    00067 namespace std
    00068 {
    00069   using namespace __gnu_internal;
    00070
    00071   extern istream cin;
    00072   extern ostream cout;
    00073   extern ostream cerr;
    00074   extern ostream clog;
    00075
    00076 #ifdef _GLIBCXX_USE_WCHAR_T
    00077   extern wistream wcin;
    00078   extern wostream wcout;
    00079   extern wostream wcerr;
    00080   extern wostream wclog;
    00081 #endif
    00082
    00083   ios_base::Init::Init()
    00084   {
    00085     if (__gnu_cxx::__exchange_and_add(&_S_refcount, 1) == 0)
    00086       {
    00087     // Standard streams default to synced with "C" operations.
    00088     _S_synced_with_stdio = true;
    00089
    00090     new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout);
    00091     new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin);
    00092     new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr);
    00093
    00094     // The standard streams are constructed once only and never
    00095     // destroyed.
    00096     new (&cout) ostream(&buf_cout_sync);
    00097     new (&cin) istream(&buf_cin_sync);
    00098     new (&cerr) ostream(&buf_cerr_sync);
    00099     new (&clog) ostream(&buf_cerr_sync);
    00100     cin.tie(&cout);
    00101     cerr.flags(ios_base::unitbuf);
    00102
    00103 #ifdef _GLIBCXX_USE_WCHAR_T
    00104     new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout);
    00105     new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin);
    00106     new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr);
    00107
    00108     new (&wcout) wostream(&buf_wcout_sync);
    00109     new (&wcin) wistream(&buf_wcin_sync);
    00110     new (&wcerr) wostream(&buf_wcerr_sync);
    00111     new (&wclog) wostream(&buf_wcerr_sync);
    00112     wcin.tie(&wcout);
    00113     wcerr.flags(ios_base::unitbuf);
    00114 #endif
    00115
    00116     // NB: Have to set refcount above one, so that standard
    00117     // streams are not re-initialized with uses of ios_base::Init
    00118     // besides <iostream> static object, ie just using <ios> with
    00119     // ios_base::Init objects.
    00120     __gnu_cxx::__atomic_add(&_S_refcount, 1);
    00121       }
    00122   }
    00123
    00124   ios_base::Init::~Init()
    00125   {
    00126     if (__gnu_cxx::__exchange_and_add(&_S_refcount, -1) == 2)
    00127       {
    00128     // Catch any exceptions thrown by basic_ostream::flush()
    00129     try
    00130       {
    00131         // Flush standard output streams as required by 27.4.2.1.6
    00132         cout.flush();
    00133         cerr.flush();
    00134         clog.flush();
    00135
    00136 #ifdef _GLIBCXX_USE_WCHAR_T
    00137         wcout.flush();
    00138         wcerr.flush();
    00139         wclog.flush();
    00140 #endif
    00141       }
    00142     catch (...)
    00143       { }
    00144       }
    00145   }
    00146
    00147   bool
    00148   ios_base::sync_with_stdio(bool __sync)
    00149   {
    00150     // _GLIBCXX_RESOLVE_LIB_DEFECTS
    00151     // 49.  Underspecification of ios_base::sync_with_stdio
    00152     bool __ret = ios_base::Init::_S_synced_with_stdio;
    00153
    00154     // Turn off sync with C FILE* for cin, cout, cerr, clog iff
    00155     // currently synchronized.
    00156     if (!__sync && __ret)
    00157       {
    00158     ios_base::Init::_S_synced_with_stdio = __sync;
    00159
    00160     // Explicitly call dtors to free any memory that is
    00161     // dynamically allocated by filebuf ctor or member functions,
    00162     // but don't deallocate all memory by calling operator delete.
    00163     buf_cout_sync.~stdio_sync_filebuf<char>();
    00164     buf_cin_sync.~stdio_sync_filebuf<char>();
    00165     buf_cerr_sync.~stdio_sync_filebuf<char>();
    00166
    00167 #ifdef _GLIBCXX_USE_WCHAR_T
    00168     buf_wcout_sync.~stdio_sync_filebuf<wchar_t>();
    00169     buf_wcin_sync.~stdio_sync_filebuf<wchar_t>();
    00170     buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>();
    00171 #endif
    00172
    00173     // Create stream buffers for the standard streams and use
    00174     // those buffers without destroying and recreating the
    00175     // streams.
    00176     new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out);
    00177     new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in);
    00178     new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out);
    00179     cout.rdbuf(&buf_cout);
    00180     cin.rdbuf(&buf_cin);
    00181     cerr.rdbuf(&buf_cerr);
    00182     clog.rdbuf(&buf_cerr);
    00183
    00184 #ifdef _GLIBCXX_USE_WCHAR_T
    00185     new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out);
    00186     new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in);
    00187     new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out);
    00188     wcout.rdbuf(&buf_wcout);
    00189     wcin.rdbuf(&buf_wcin);
    00190     wcerr.rdbuf(&buf_wcerr);
    00191     wclog.rdbuf(&buf_wcerr);
    00192 #endif
    00193       }
    00194     return __ret;
    00195   }
    00196 } // namespace std