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     // Make sure the standard streams are constructed.
00159     ios_base::Init __init;
00160 
00161     ios_base::Init::_S_synced_with_stdio = __sync;
00162 
00163     // Explicitly call dtors to free any memory that is
00164     // dynamically allocated by filebuf ctor or member functions,
00165     // but don't deallocate all memory by calling operator delete.
00166     buf_cout_sync.~stdio_sync_filebuf<char>();
00167     buf_cin_sync.~stdio_sync_filebuf<char>();
00168     buf_cerr_sync.~stdio_sync_filebuf<char>();
00169 
00170 #ifdef _GLIBCXX_USE_WCHAR_T
00171     buf_wcout_sync.~stdio_sync_filebuf<wchar_t>();
00172     buf_wcin_sync.~stdio_sync_filebuf<wchar_t>();
00173     buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>();
00174 #endif
00175 
00176     // Create stream buffers for the standard streams and use
00177     // those buffers without destroying and recreating the
00178     // streams.
00179     new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out);
00180     new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in);
00181     new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out);
00182     cout.rdbuf(&buf_cout);
00183     cin.rdbuf(&buf_cin);
00184     cerr.rdbuf(&buf_cerr);
00185     clog.rdbuf(&buf_cerr);
00186     
00187 #ifdef _GLIBCXX_USE_WCHAR_T
00188     new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out);
00189     new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in);
00190     new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out);
00191     wcout.rdbuf(&buf_wcout);
00192     wcin.rdbuf(&buf_wcin);
00193     wcerr.rdbuf(&buf_wcerr);
00194     wclog.rdbuf(&buf_wcerr);
00195 #endif
00196       }
00197     return __ret; 
00198   }
00199 } // namespace std

Generated on Fri May 6 01:08:59 2005 for libstdc++-v3 Source by  doxygen 1.4.2