os/ossrv/genericopenlibs/cppstdlib/stl/src/iostream.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2  * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
     3  *
     4  * Copyright (c) 1999
     5  * Silicon Graphics Computer Systems, Inc.
     6  *
     7  * Copyright (c) 1999
     8  * Boris Fomitchev
     9  *
    10  * This material is provided "as is", with absolutely no warranty expressed
    11  * or implied. Any use is at your own risk.
    12  *
    13  * Permission to use or copy this software for any purpose is hereby granted
    14  * without fee, provided the above notices are retained on all copies.
    15  * Permission to modify the code and to distribute modified code is granted,
    16  * provided the above notices are retained, and a notice that the code was
    17  * modified is included with the above copyright notice.
    18  *
    19  */
    20 #include "stlport_prefix.h"
    21 
    22 #include <istream>
    23 #include <fstream>
    24 #if defined (_STLP_MSVC) || defined (__MWERKS__) || defined (__ICL) || defined (__ISCPP__) || defined(__SYMBIAN32__)
    25 #  define _STLP_USE_NOT_INIT_SEGMENT
    26 #  include <iostream>
    27 #endif
    28 
    29 #if defined(__SYMBIAN32__WSD__)
    30 # include "libstdcppwsd.h"
    31 #endif
    32 
    33 #include "stdio_streambuf.h"
    34 #include "aligned_buffer.h"
    35 #include "_stdio_file.h"
    36 #include "c_locale.h"
    37 
    38 // boris : note this is repeated in <iostream>
    39 #ifndef _STLP_USE_NAMESPACES
    40 // in case of SGI iostreams, we have to rename our streams not to clash with those
    41 // provided in native lib
    42 #  define cin _STLP_cin
    43 #  define cout _STLP_cout
    44 #  define cerr _STLP_cerr
    45 #  define clog _STLP_clog
    46 #endif
    47 
    48 _STLP_BEGIN_NAMESPACE
    49 
    50 #if defined (__BORLANDC__) && ! defined (_STLP_USE_GLIBC)
    51 using _STLP_VENDOR_CSTD::_streams;
    52 #endif
    53 
    54 // This file handles iostream initialization.  It is inherently
    55 // nonportable, since the C++ language definition provides no mechanism
    56 // for controlling order of initialization of nonlocal objects.
    57 // Initialization has three parts, which must be performed in the following
    58 // order:
    59 //  (1) Initialize the locale system
    60 //  (2) Call the constructors for the eight global stream objects.
    61 //  (3) Create streambufs for the global stream objects, and initialize
    62 //      the stream objects by calling the init() member function.
    63 
    64 
    65 #if defined (_STLP_USE_NOT_INIT_SEGMENT)
    66 
    67 // Definitions of the eight global I/O objects that are declared in
    68 // <iostream>. For some compilers we use pragmas to put the global I/O
    69 // objects into an initialization segment that will not
    70 // be executed. We then explicitly invoke the constructors
    71 // with placement new in ios_base::_S_initialize()
    72 
    73 #  if defined (__MWERKS__)
    74 #    pragma suppress_init_code on
    75 #  else
    76 #    pragma init_seg("STLPORT_NO_INIT")
    77 #  endif
    78 
    79 #if defined(__SYMBIAN32__NO_STATIC_IMPORTS__)
    80 istream cin(0);
    81 
    82 #  ifdef _STLP_REDIRECT_STDSTREAMS
    83 ofstream cout;
    84 ofstream cerr;
    85 ofstream clog;
    86 #  else
    87 ostream cout(0);
    88 ostream cerr(0);
    89 ostream clog(0);
    90 #  endif
    91 
    92 #ifndef _STLP_NO_WCHAR_T
    93 wistream wcin(0);
    94 wostream wcout(0);
    95 wostream wcerr(0);
    96 wostream wclog(0);
    97 #endif
    98 
    99 _STLP_DECLSPEC ostream& get_cerr()
   100 	{	
   101 	return cerr;
   102 	}
   103 
   104 _STLP_DECLSPEC ostream& get_cout()
   105 	{
   106     return cout;
   107 	}
   108 
   109 _STLP_DECLSPEC ostream& get_clog()
   110 	{
   111     return clog;
   112 	}
   113 
   114 _STLP_DECLSPEC istream& get_cin()
   115 	{
   116     return cin;
   117 	}
   118 
   119 #  ifndef _STLP_NO_WCHAR_T
   120 _STLP_DECLSPEC wostream& get_wcerr()
   121 	{
   122 	return wcerr;
   123 	}
   124 
   125 _STLP_DECLSPEC wostream& get_wcout()
   126 	{
   127 	return wcout;
   128 	}
   129 
   130 _STLP_DECLSPEC wostream& get_wclog()
   131 	{
   132     return wclog;
   133 	}
   134 
   135 _STLP_DECLSPEC wistream& get_wcin()
   136 	{
   137     return wcin;
   138 	}   
   139 #endif //_STLP_NO_WCHAR_T
   140 
   141 
   142 # elif defined (__SYMBIAN32__WSD__)
   143 
   144 _STLP_DECLSPEC ostream& get_cerr()
   145 	{	
   146 	return *get_libcpp_wsd().wsd_cerr;
   147 	}
   148 
   149 _STLP_DECLSPEC ostream& get_cout()
   150 	{
   151     return *get_libcpp_wsd().wsd_cout;
   152 	}
   153 
   154 _STLP_DECLSPEC ostream& get_clog()
   155 	{
   156     return *get_libcpp_wsd().wsd_clog;
   157 	}
   158 
   159 _STLP_DECLSPEC istream& get_cin()
   160 	{
   161     return *get_libcpp_wsd().wsd_cin;
   162 	}
   163 
   164 #  ifndef _STLP_NO_WCHAR_T
   165 _STLP_DECLSPEC wostream& get_wcerr()
   166 	{
   167 	return *get_libcpp_wsd().wsd_wcerr;
   168 	}
   169 
   170 _STLP_DECLSPEC wostream& get_wcout()
   171 	{
   172 	return *get_libcpp_wsd().wsd_wcout;
   173 	}
   174 
   175 _STLP_DECLSPEC wostream& get_wclog()
   176 	{
   177     return *get_libcpp_wsd().wsd_wclog;
   178 	}
   179 
   180 _STLP_DECLSPEC wistream& get_wcin()
   181 	{
   182     return *get_libcpp_wsd().wsd_wcin;
   183 	}   
   184 #endif //_STLP_NO_WCHAR_T
   185 
   186 
   187 #define _S_count 			get_ios_base_Init_S_count()
   188 #define _S_was_synced 		get_ios_base_S_was_synced()
   189 
   190 #else
   191 _STLP_DECLSPEC istream cin(0);
   192 
   193 #  ifdef _STLP_REDIRECT_STDSTREAMS
   194 _STLP_DECLSPEC ofstream cout;
   195 _STLP_DECLSPEC ofstream cerr;
   196 _STLP_DECLSPEC ofstream clog;
   197 #  else
   198 _STLP_DECLSPEC ostream cout(0);
   199 _STLP_DECLSPEC ostream cerr(0);
   200 _STLP_DECLSPEC ostream clog(0);
   201 #  endif
   202 
   203 #ifndef _STLP_NO_WCHAR_T
   204 _STLP_DECLSPEC wistream wcin(0);
   205 _STLP_DECLSPEC wostream wcout(0);
   206 _STLP_DECLSPEC wostream wcerr(0);
   207 _STLP_DECLSPEC wostream wclog(0);
   208 #endif
   209 #endif //__SYMBIAN32__NO_STATIC_IMPORTS__
   210 
   211 #  if defined (__MWERKS__)
   212 #    pragma suppress_init_code off
   213 #  endif
   214 
   215 #else
   216 
   217 // Definitions of the eight global I/O objects that are declared in
   218 // <iostream>.  Disgusting hack: we deliberately define them with the
   219 // wrong types so that the constructors don't get run automatically.
   220 // We need special tricks to make sure that these objects are struct-
   221 // aligned rather than byte-aligned.
   222 
   223 // This is not portable.  Declaring a variable with different types in
   224 // two translations units is "undefined", according to the C++ standard.
   225 // Most compilers, however, silently accept this instead of diagnosing
   226 // it as an error.
   227 
   228 #  ifndef __DMC__
   229 _STLP_DECLSPEC _Stl_aligned_buffer<istream> cin;
   230 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cout;
   231 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cerr;
   232 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> clog;
   233 #  else
   234 _Stl_aligned_buffer<istream> cin;
   235 _Stl_aligned_buffer<ostream> cout;
   236 _Stl_aligned_buffer<ostream> cerr;
   237 _Stl_aligned_buffer<ostream> clog;
   238 
   239 #    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")
   240 #    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")
   241 #    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")
   242 #    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")
   243 #  endif
   244 
   245 #  ifndef _STLP_NO_WCHAR_T
   246 
   247 #    ifndef __DMC__
   248 _STLP_DECLSPEC _Stl_aligned_buffer<wistream> wcin;
   249 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcout;
   250 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcerr;
   251 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wclog;
   252 #    else
   253 _Stl_aligned_buffer<wistream> wcin;
   254 _Stl_aligned_buffer<wostream> wcout;
   255 _Stl_aligned_buffer<wostream> wcerr;
   256 _Stl_aligned_buffer<wostream> wclog;
   257 
   258 #      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")
   259 #      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")
   260 #      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")
   261 #      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")
   262 #    endif
   263 #  endif
   264 #endif /* STL_MSVC || __MWERKS__ */
   265 
   266 // Member functions from class ios_base and ios_base::Init
   267 #if !defined(__SYMBIAN32__WSD__)
   268 long ios_base::Init::_S_count = 0;
   269 // by default, those are synced
   270 bool ios_base::_S_was_synced = true;
   271 # endif //__SYMBIAN32__WSD__
   272 
   273 _STLP_DECLSPEC ios_base::Init::Init() {
   274   if (_S_count++ == 0) {
   275     _Locale_init();
   276     ios_base::_S_initialize();
   277     _Filebuf_base::_S_initialize();
   278   }
   279 }
   280 
   281 _STLP_DECLSPEC ios_base::Init::~Init() {
   282   if (--_S_count == 0) {
   283     ios_base::_S_uninitialize();
   284     _Locale_final();
   285   }
   286 }
   287  
   288 #ifdef __SYMBIAN32__
   289 #undef _FILE_fd
   290 #define _FILE_fd fileno
   291 #endif
   292 
   293 static filebuf*
   294 _Stl_create_filebuf(FILE* f, ios_base::openmode mode ) {
   295   basic_filebuf<char, char_traits<char> >* result =
   296     new basic_filebuf<char, char_traits<char> >();
   297 
   298   _STLP_TRY {
   299     result->_M_open(_FILE_fd(f), mode);
   300   }
   301   _STLP_CATCH_ALL {}
   302 
   303   if (!result->is_open()) {
   304     delete result;
   305     result = 0;
   306   }
   307   return result;
   308 }
   309 
   310 #if !defined (_STLP_NO_WCHAR_T)
   311 static wfilebuf*
   312 _Stl_create_wfilebuf(FILE* f, ios_base::openmode mode) {
   313   basic_filebuf<wchar_t, char_traits<wchar_t> >* result =
   314     new basic_filebuf<wchar_t, char_traits<wchar_t> >();
   315 
   316   _STLP_TRY {
   317     result->_M_open(_FILE_fd(f), mode);
   318   }
   319   _STLP_CATCH_ALL {}
   320 
   321   if (!result->is_open()) {
   322     delete result;
   323     result = 0;
   324   }
   325   return result;
   326 }
   327 #endif
   328 
   329 void  _STLP_CALL ios_base::_S_initialize() {
   330 #if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
   331   using _STLP_PRIV stdio_istreambuf;
   332   using _STLP_PRIV stdio_ostreambuf;
   333 #endif
   334   _STLP_TRY {
   335     istream* ptr_cin  = new(static_cast<void*>(&cin))  istream(0);
   336 #  ifdef _STLP_REDIRECT_STDSTREAMS
   337     ofstream* ptr_cout = new(static_cast<void*>(&cout)) ofstream;
   338     ofstream* ptr_cerr = new(static_cast<void*>(&cerr)) ofstream;
   339     ofstream* ptr_clog = new(static_cast<void*>(&clog)) ofstream;
   340 
   341     // Initialize the four narrow stream objects.
   342     if (_S_was_synced) {
   343       ptr_cin->init(new stdio_istreambuf(stdin));
   344       ptr_cout->open("/stdout.txt", ios::out);
   345       ptr_cerr->open("/stderr.txt", ios::out);
   346       ptr_clog->open("/stdlog.txt", ios::out);
   347     } else {
   348       ptr_cin->init(_Stl_create_filebuf(stdin, ios_base::in));
   349       ptr_cin->init(_Stl_create_filebuf(stdout, ios_base::out));
   350       ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
   351       ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
   352     }
   353     ptr_cin->tie(ptr_cout);
   354     ptr_cerr->setf(ios_base::unitbuf);
   355 #  else
   356     ostream* ptr_cout = new(static_cast<void*>(&cout)) ostream(0);
   357     ostream* ptr_cerr = new(static_cast<void*>(&cerr)) ostream(0);
   358     ostream* ptr_clog = new(static_cast<void*>(&clog)) ostream(0);
   359 
   360     // Initialize the four narrow stream objects.
   361     if (_S_was_synced) {
   362       ptr_cin->init(new stdio_istreambuf(stdin));
   363       ptr_cout->init(new stdio_ostreambuf(stdout));
   364       ptr_cerr->init(new stdio_ostreambuf(stdout));
   365       ptr_clog->init(new stdio_ostreambuf(stdout));
   366     } else {
   367       ptr_cin->init(_Stl_create_filebuf(stdin, ios_base::in));
   368       ptr_cin->init(_Stl_create_filebuf(stdout, ios_base::out));
   369       ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
   370       ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
   371     }
   372     ptr_cin->tie(ptr_cout);
   373     ptr_cerr->setf(ios_base::unitbuf);
   374 #  endif /* _STLP_REDIRECT_STDSTREAMS */
   375 
   376 #  ifndef _STLP_NO_WCHAR_T
   377     // Run constructors for the four wide stream objects.
   378     wistream* ptr_wcin  = new(&wcin)  wistream(0);
   379     wostream* ptr_wcout = new(&wcout) wostream(0);
   380     wostream* ptr_wcerr = new(&wcerr) wostream(0);
   381     wostream* ptr_wclog = new(&wclog) wostream(0);
   382 
   383     wfilebuf* win  = _Stl_create_wfilebuf(stdin, ios_base::in);
   384     wfilebuf* wout = _Stl_create_wfilebuf(stdout, ios_base::out);
   385     wfilebuf* werr = _Stl_create_wfilebuf(stdout, ios_base::out);
   386     wfilebuf* wlog = _Stl_create_wfilebuf(stdout, ios_base::out);
   387 
   388     ptr_wcin->init(win);
   389     ptr_wcout->init(wout);
   390     ptr_wcerr->init(werr);
   391     ptr_wclog->init(wlog);
   392 
   393     ptr_wcin->tie(ptr_wcout);
   394     ptr_wcerr->setf(ios_base::unitbuf);
   395 
   396 #  endif /*  _STLP_NO_WCHAR_T */
   397   }
   398 
   399   _STLP_CATCH_ALL {}
   400 }
   401 
   402 void _STLP_CALL ios_base::_S_uninitialize() {
   403   // Note that destroying output streambufs flushes the buffers.
   404 
   405   istream* ptr_cin  = &cin;
   406   ostream* ptr_cout = &cout;
   407   ostream* ptr_cerr = &cerr;
   408   ostream* ptr_clog = &clog;
   409 
   410 #ifndef _STLP_NO_WCHAR_T
   411   wistream* ptr_wcin  = &wcin;
   412   wostream* ptr_wcout = &wcout;
   413   wostream* ptr_wcerr = &wcerr;
   414   wostream* ptr_wclog = &wclog;
   415 #endif
   416 
   417   // we don't want any exceptions being thrown here
   418   ptr_cin->exceptions(0);
   419   ptr_cout->exceptions(0);
   420   ptr_cerr->exceptions(0);
   421   ptr_clog->exceptions(0);
   422 
   423   delete ptr_cin->rdbuf(0);
   424   delete ptr_cout->rdbuf(0);
   425   delete ptr_cerr->rdbuf(0);
   426   delete ptr_clog->rdbuf(0);
   427 
   428   _Destroy(ptr_cin);
   429   _Destroy(ptr_cout);
   430   _Destroy(ptr_cerr);
   431   _Destroy(ptr_clog);
   432 
   433 #ifndef _STLP_NO_WCHAR_T
   434   // we don't want any exceptions being thrown here
   435   ptr_wcin->exceptions(0);
   436   ptr_wcout->exceptions(0);
   437   ptr_wcerr->exceptions(0);
   438   ptr_wclog->exceptions(0);
   439 
   440   delete ptr_wcin->rdbuf(0);
   441   delete ptr_wcout->rdbuf(0);
   442   delete ptr_wcerr->rdbuf(0);
   443   delete ptr_wclog->rdbuf(0);
   444 
   445   _Destroy(ptr_wcin);
   446   _Destroy(ptr_wcout);
   447   _Destroy(ptr_wcerr);
   448   _Destroy(ptr_wclog);
   449 #endif
   450 }
   451 
   452 
   453 _STLP_DECLSPEC bool _STLP_CALL ios_base::sync_with_stdio(bool sync) {
   454 #  if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
   455   using _STLP_PRIV stdio_istreambuf;
   456   using _STLP_PRIV stdio_ostreambuf;
   457 #  endif
   458 
   459   bool was_synced =  _S_was_synced;
   460 
   461   // if by any chance we got there before std streams initialization,
   462   // just set the sync flag and exit
   463   if (Init::_S_count == 0) {
   464     _S_was_synced = sync;
   465     return was_synced;
   466   }
   467 
   468   istream* ptr_cin  = &cin;
   469   ostream* ptr_cout = &cout;
   470   ostream* ptr_cerr = &cerr;
   471   ostream* ptr_clog = &clog;
   472 
   473   streambuf* old_cin  = ptr_cin->rdbuf();
   474   streambuf* old_cout = ptr_cout->rdbuf();
   475   streambuf* old_cerr = ptr_cerr->rdbuf();
   476   streambuf* old_clog = ptr_clog->rdbuf();
   477 
   478   streambuf* new_cin  = 0;
   479   streambuf* new_cout = 0;
   480   streambuf* new_cerr = 0;
   481   streambuf* new_clog = 0;
   482 
   483   _STLP_TRY {
   484     if (sync && !was_synced) {
   485       new_cin  = new stdio_istreambuf(stdin);
   486       new_cout = new stdio_ostreambuf(stdout);
   487       new_cerr = new stdio_ostreambuf(stdout);
   488       new_clog = new stdio_ostreambuf(stdout);
   489     }
   490     else if (!sync && was_synced) {
   491       new_cin  = _Stl_create_filebuf(stdin, ios_base::in);
   492       new_cout = _Stl_create_filebuf(stdout, ios_base::out);
   493       new_cerr = _Stl_create_filebuf(stdout, ios_base::out);
   494       new_clog = _Stl_create_filebuf(stdout, ios_base::out);
   495     }
   496   }
   497   _STLP_CATCH_ALL {}
   498 
   499   if (new_cin && new_cout && new_cerr && new_clog) {
   500     ptr_cin->rdbuf(new_cin);
   501     ptr_cout->rdbuf(new_cout);
   502     ptr_cerr->rdbuf(new_cerr);
   503     ptr_clog->rdbuf(new_clog);
   504 
   505     delete old_cin;
   506     delete old_cout;
   507     delete old_cerr;
   508     delete old_clog;
   509   }
   510   else {
   511     delete new_cin;
   512     delete new_cout;
   513     delete new_cerr;
   514     delete new_clog;
   515   }
   516 
   517   return was_synced;
   518 }
   519 
   520 _STLP_END_NAMESPACE
   521 
   522 // Local Variables:
   523 // mode:C++
   524 // End: