/home/ntakagi/work/STLport-5.1.5/src/iostream.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */
00018 #include "stlport_prefix.h"
00019 
00020 #include <istream>
00021 #include <fstream>
00022 #if defined (_STLP_MSVC) || defined (__MWERKS__) || defined (__ICL) || defined (__ISCPP__)
00023 #  define _STLP_USE_NOT_INIT_SEGMENT
00024 #  include <iostream>
00025 #endif
00026 
00027 #include "stdio_streambuf.h"
00028 #include "aligned_buffer.h"
00029 #include "_stdio_file.h"
00030 #include "c_locale.h"
00031 
00032 // boris : note this is repeated in <iostream>
00033 #ifndef _STLP_USE_NAMESPACES
00034 // in case of SGI iostreams, we have to rename our streams not to clash with those
00035 // provided in native lib
00036 #  define cin _STLP_cin
00037 #  define cout _STLP_cout
00038 #  define cerr _STLP_cerr
00039 #  define clog _STLP_clog
00040 #endif
00041 
00042 _STLP_BEGIN_NAMESPACE
00043 
00044 #if defined (__BORLANDC__) && ! defined (_STLP_USE_GLIBC)
00045 using _STLP_VENDOR_CSTD::_streams;
00046 #endif
00047 
00048 // This file handles iostream initialization.  It is inherently
00049 // nonportable, since the C++ language definition provides no mechanism
00050 // for controlling order of initialization of nonlocal objects.
00051 // Initialization has three parts, which must be performed in the following
00052 // order:
00053 //  (1) Initialize the locale system
00054 //  (2) Call the constructors for the eight global stream objects.
00055 //  (3) Create streambufs for the global stream objects, and initialize
00056 //      the stream objects by calling the init() member function.
00057 
00058 
00059 #if defined (_STLP_USE_NOT_INIT_SEGMENT)
00060 
00061 // Definitions of the eight global I/O objects that are declared in
00062 // <iostream>. For some compilers we use pragmas to put the global I/O
00063 // objects into an initialization segment that will not
00064 // be executed. We then explicitly invoke the constructors
00065 // with placement new in ios_base::_S_initialize()
00066 
00067 #  if defined (__MWERKS__)
00068 #    pragma suppress_init_code on
00069 #  else
00070 #    pragma init_seg("STLPORT_NO_INIT")
00071 #  endif
00072 
00073 _STLP_DECLSPEC istream cin(0);
00074 
00075 #  ifdef _STLP_REDIRECT_STDSTREAMS
00076 _STLP_DECLSPEC ofstream cout;
00077 _STLP_DECLSPEC ofstream cerr;
00078 _STLP_DECLSPEC ofstream clog;
00079 #  else
00080 _STLP_DECLSPEC ostream cout(0);
00081 _STLP_DECLSPEC ostream cerr(0);
00082 _STLP_DECLSPEC ostream clog(0);
00083 #  endif
00084 
00085 #  ifndef _STLP_NO_WCHAR_T
00086 _STLP_DECLSPEC wistream wcin(0);
00087 _STLP_DECLSPEC wostream wcout(0);
00088 _STLP_DECLSPEC wostream wcerr(0);
00089 _STLP_DECLSPEC wostream wclog(0);
00090 #  endif
00091 
00092 #  if defined (__MWERKS__)
00093 #    pragma suppress_init_code off
00094 #  endif
00095 
00096 #else
00097 
00098 // Definitions of the eight global I/O objects that are declared in
00099 // <iostream>.  Disgusting hack: we deliberately define them with the
00100 // wrong types so that the constructors don't get run automatically.
00101 // We need special tricks to make sure that these objects are struct-
00102 // aligned rather than byte-aligned.
00103 
00104 // This is not portable.  Declaring a variable with different types in
00105 // two translations units is "undefined", according to the C++ standard.
00106 // Most compilers, however, silently accept this instead of diagnosing
00107 // it as an error.
00108 
00109 #  ifndef __DMC__
00110 _STLP_DECLSPEC _Stl_aligned_buffer<istream> cin;
00111 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cout;
00112 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cerr;
00113 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> clog;
00114 #  else
00115 _Stl_aligned_buffer<istream> cin;
00116 _Stl_aligned_buffer<ostream> cout;
00117 _Stl_aligned_buffer<ostream> cerr;
00118 _Stl_aligned_buffer<ostream> clog;
00119 
00120 #    pragma alias("?cin@std@@3V?$basic_istream@std@DV?$char_traits@std@D@1@@1@A", "?cin@std@@3T?$_Stl_aligned_buffer@std@V?$basic_istream@std@DV?$char_traits@std@D@1@@1@@1@A")
00121 #    pragma alias("?cout@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?cout@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A")
00122 #    pragma alias("?cerr@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?cerr@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A")
00123 #    pragma alias("?clog@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?clog@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A")
00124 #  endif
00125 
00126 #  ifndef _STLP_NO_WCHAR_T
00127 
00128 #    ifndef __DMC__
00129 _STLP_DECLSPEC _Stl_aligned_buffer<wistream> wcin;
00130 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcout;
00131 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcerr;
00132 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wclog;
00133 #    else
00134 _Stl_aligned_buffer<wistream> wcin;
00135 _Stl_aligned_buffer<wostream> wcout;
00136 _Stl_aligned_buffer<wostream> wcerr;
00137 _Stl_aligned_buffer<wostream> wclog;
00138 
00139 #      pragma alias("?wcin@std@@3V?$basic_istream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcin@std@@3T?$_Stl_aligned_buffer@std@V?$basic_istream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
00140 #      pragma alias("?wcout@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcout@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
00141 #      pragma alias("?wcerr@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcerr@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
00142 #      pragma alias("?wclog@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wclog@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
00143 #    endif
00144 #  endif
00145 #endif /* STL_MSVC || __MWERKS__ */
00146 
00147 // Member functions from class ios_base and ios_base::Init
00148 
00149 long ios_base::Init::_S_count = 0;
00150 // by default, those are synced
00151 bool ios_base::_S_was_synced = true;
00152 
00153 ios_base::Init::Init() {
00154   if (_S_count++ == 0) {
00155     _Locale_init();
00156     ios_base::_S_initialize();
00157     _Filebuf_base::_S_initialize();
00158   }
00159 }
00160 
00161 ios_base::Init::~Init() {
00162   if (--_S_count == 0) {
00163     ios_base::_S_uninitialize();
00164     _Locale_final();
00165   }
00166 }
00167 
00168 static filebuf*
00169 _Stl_create_filebuf(FILE* f, ios_base::openmode mode ) {
00170   basic_filebuf<char, char_traits<char> >* result =
00171     new basic_filebuf<char, char_traits<char> >();
00172 
00173   _STLP_TRY {
00174     result->_M_open(_FILE_fd(f), mode);
00175   }
00176   _STLP_CATCH_ALL {}
00177 
00178   if (!result->is_open()) {
00179     delete result;
00180     result = 0;
00181   }
00182   return result;
00183 }
00184 
00185 #if !defined (_STLP_NO_WCHAR_T)
00186 static wfilebuf*
00187 _Stl_create_wfilebuf(FILE* f, ios_base::openmode mode) {
00188   basic_filebuf<wchar_t, char_traits<wchar_t> >* result =
00189     new basic_filebuf<wchar_t, char_traits<wchar_t> >();
00190 
00191   _STLP_TRY {
00192     result->_M_open(_FILE_fd(f), mode);
00193   }
00194   _STLP_CATCH_ALL {}
00195 
00196   if (!result->is_open()) {
00197     delete result;
00198     result = 0;
00199   }
00200   return result;
00201 }
00202 #endif
00203 
00204 void  _STLP_CALL ios_base::_S_initialize() {
00205 #if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
00206   using _STLP_PRIV stdio_istreambuf;
00207   using _STLP_PRIV stdio_ostreambuf;
00208 #endif
00209   _STLP_TRY {
00210     istream* ptr_cin  = new(static_cast<void*>(&cin))  istream(0);
00211 #  ifdef _STLP_REDIRECT_STDSTREAMS
00212     ofstream* ptr_cout = new(static_cast<void*>(&cout)) ofstream;
00213     ofstream* ptr_cerr = new(static_cast<void*>(&cerr)) ofstream;
00214     ofstream* ptr_clog = new(static_cast<void*>(&clog)) ofstream;
00215 
00216     // Initialize the four narrow stream objects.
00217     if (_S_was_synced) {
00218       ptr_cin->init(new stdio_istreambuf(stdin));
00219       ptr_cout->open("/stdout.txt", ios::out);
00220       ptr_cerr->open("/stderr.txt", ios::out);
00221       ptr_clog->open("/stdlog.txt", ios::out);
00222     } else {
00223       ptr_cin->init(_Stl_create_filebuf(stdin, ios_base::in));
00224       ptr_cin->init(_Stl_create_filebuf(stdout, ios_base::out));
00225       ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
00226       ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
00227     }
00228     ptr_cin->tie(ptr_cout);
00229     ptr_cerr->setf(ios_base::unitbuf);
00230 #  else
00231     ostream* ptr_cout = new(static_cast<void*>(&cout)) ostream(0);
00232     ostream* ptr_cerr = new(static_cast<void*>(&cerr)) ostream(0);
00233     ostream* ptr_clog = new(static_cast<void*>(&clog)) ostream(0);
00234 
00235     // Initialize the four narrow stream objects.
00236     if (_S_was_synced) {
00237       ptr_cin->init(new stdio_istreambuf(stdin));
00238       ptr_cout->init(new stdio_ostreambuf(stdout));
00239       ptr_cerr->init(new stdio_ostreambuf(stderr));
00240       ptr_clog->init(new stdio_ostreambuf(stderr));
00241     } else {
00242       ptr_cin->init(_Stl_create_filebuf(stdin, ios_base::in));
00243       ptr_cin->init(_Stl_create_filebuf(stdout, ios_base::out));
00244       ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
00245       ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
00246     }
00247     ptr_cin->tie(ptr_cout);
00248     ptr_cerr->setf(ios_base::unitbuf);
00249 #  endif /* _STLP_REDIRECT_STDSTREAMS */
00250 
00251 #  ifndef _STLP_NO_WCHAR_T
00252     // Run constructors for the four wide stream objects.
00253     wistream* ptr_wcin  = new(&wcin)  wistream(0);
00254     wostream* ptr_wcout = new(&wcout) wostream(0);
00255     wostream* ptr_wcerr = new(&wcerr) wostream(0);
00256     wostream* ptr_wclog = new(&wclog) wostream(0);
00257 
00258     wfilebuf* win  = _Stl_create_wfilebuf(stdin, ios_base::in);
00259     wfilebuf* wout = _Stl_create_wfilebuf(stdout, ios_base::out);
00260     wfilebuf* werr = _Stl_create_wfilebuf(stderr, ios_base::out);
00261     wfilebuf* wlog = _Stl_create_wfilebuf(stderr, ios_base::out);
00262 
00263     ptr_wcin->init(win);
00264     ptr_wcout->init(wout);
00265     ptr_wcerr->init(werr);
00266     ptr_wclog->init(wlog);
00267 
00268     ptr_wcin->tie(ptr_wcout);
00269     ptr_wcerr->setf(ios_base::unitbuf);
00270 
00271 #  endif /*  _STLP_NO_WCHAR_T */
00272   }
00273 
00274   _STLP_CATCH_ALL {}
00275 }
00276 
00277 void _STLP_CALL ios_base::_S_uninitialize() {
00278   // Note that destroying output streambufs flushes the buffers.
00279 
00280   istream* ptr_cin  = &cin;
00281   ostream* ptr_cout = &cout;
00282   ostream* ptr_cerr = &cerr;
00283   ostream* ptr_clog = &clog;
00284 
00285 #ifndef _STLP_NO_WCHAR_T
00286   wistream* ptr_wcin  = &wcin;
00287   wostream* ptr_wcout = &wcout;
00288   wostream* ptr_wcerr = &wcerr;
00289   wostream* ptr_wclog = &wclog;
00290 #endif
00291 
00292   // we don't want any exceptions being thrown here
00293   ptr_cin->exceptions(0);
00294   ptr_cout->exceptions(0);
00295   ptr_cerr->exceptions(0);
00296   ptr_clog->exceptions(0);
00297 
00298   delete ptr_cin->rdbuf(0);
00299   delete ptr_cout->rdbuf(0);
00300   delete ptr_cerr->rdbuf(0);
00301   delete ptr_clog->rdbuf(0);
00302 
00303   _Destroy(ptr_cin);
00304   _Destroy(ptr_cout);
00305   _Destroy(ptr_cerr);
00306   _Destroy(ptr_clog);
00307 
00308 #ifndef _STLP_NO_WCHAR_T
00309   // we don't want any exceptions being thrown here
00310   ptr_wcin->exceptions(0);
00311   ptr_wcout->exceptions(0);
00312   ptr_wcerr->exceptions(0);
00313   ptr_wclog->exceptions(0);
00314 
00315   delete ptr_wcin->rdbuf(0);
00316   delete ptr_wcout->rdbuf(0);
00317   delete ptr_wcerr->rdbuf(0);
00318   delete ptr_wclog->rdbuf(0);
00319 
00320   _Destroy(ptr_wcin);
00321   _Destroy(ptr_wcout);
00322   _Destroy(ptr_wcerr);
00323   _Destroy(ptr_wclog);
00324 #endif
00325 }
00326 
00327 
00328 bool _STLP_CALL ios_base::sync_with_stdio(bool sync) {
00329 #  if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
00330   using _STLP_PRIV stdio_istreambuf;
00331   using _STLP_PRIV stdio_ostreambuf;
00332 #  endif
00333 
00334   bool was_synced =  _S_was_synced;
00335 
00336   // if by any chance we got there before std streams initialization,
00337   // just set the sync flag and exit
00338   if (Init::_S_count == 0) {
00339     _S_was_synced = sync;
00340     return was_synced;
00341   }
00342 
00343   istream* ptr_cin  = &cin;
00344   ostream* ptr_cout = &cout;
00345   ostream* ptr_cerr = &cerr;
00346   ostream* ptr_clog = &clog;
00347 
00348   streambuf* old_cin  = ptr_cin->rdbuf();
00349   streambuf* old_cout = ptr_cout->rdbuf();
00350   streambuf* old_cerr = ptr_cerr->rdbuf();
00351   streambuf* old_clog = ptr_clog->rdbuf();
00352 
00353   streambuf* new_cin  = 0;
00354   streambuf* new_cout = 0;
00355   streambuf* new_cerr = 0;
00356   streambuf* new_clog = 0;
00357 
00358   _STLP_TRY {
00359     if (sync && !was_synced) {
00360       new_cin  = new stdio_istreambuf(stdin);
00361       new_cout = new stdio_ostreambuf(stdout);
00362       new_cerr = new stdio_ostreambuf(stderr);
00363       new_clog = new stdio_ostreambuf(stderr);
00364     }
00365     else if (!sync && was_synced) {
00366       new_cin  = _Stl_create_filebuf(stdin, ios_base::in);
00367       new_cout = _Stl_create_filebuf(stdout, ios_base::out);
00368       new_cerr = _Stl_create_filebuf(stderr, ios_base::out);
00369       new_clog = _Stl_create_filebuf(stderr, ios_base::out);
00370     }
00371   }
00372   _STLP_CATCH_ALL {}
00373 
00374   if (new_cin && new_cout && new_cerr && new_clog) {
00375     ptr_cin->rdbuf(new_cin);
00376     ptr_cout->rdbuf(new_cout);
00377     ptr_cerr->rdbuf(new_cerr);
00378     ptr_clog->rdbuf(new_clog);
00379 
00380     delete old_cin;
00381     delete old_cout;
00382     delete old_cerr;
00383     delete old_clog;
00384   }
00385   else {
00386     delete new_cin;
00387     delete new_cout;
00388     delete new_cerr;
00389     delete new_clog;
00390   }
00391 
00392   return was_synced;
00393 }
00394 
00395 _STLP_END_NAMESPACE
00396 
00397 // Local Variables:
00398 // mode:C++
00399 // End:



Generated on Mon Mar 10 15:32:16 2008 by  doxygen 1.5.1