michael@0: /* michael@0: * Copyright (c) 1999 michael@0: * Silicon Graphics Computer Systems, Inc. michael@0: * michael@0: * Copyright (c) 1999 michael@0: * Boris Fomitchev michael@0: * michael@0: * This material is provided "as is", with absolutely no warranty expressed michael@0: * or implied. Any use is at your own risk. michael@0: * michael@0: * Permission to use or copy this software for any purpose is hereby granted michael@0: * without fee, provided the above notices are retained on all copies. michael@0: * Permission to modify the code and to distribute modified code is granted, michael@0: * provided the above notices are retained, and a notice that the code was michael@0: * modified is included with the above copyright notice. michael@0: * michael@0: */ michael@0: #include "stlport_prefix.h" michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #if defined (_STLP_MSVC) || defined (__MWERKS__) || defined (__ICL) || defined (__ISCPP__) michael@0: # define _STLP_USE_NOT_INIT_SEGMENT michael@0: # include michael@0: #endif michael@0: michael@0: #include "stdio_streambuf.h" michael@0: #include "aligned_buffer.h" michael@0: #include "_stdio_file.h" michael@0: #include "c_locale.h" michael@0: michael@0: // boris : note this is repeated in michael@0: #ifndef _STLP_USE_NAMESPACES michael@0: // in case of SGI iostreams, we have to rename our streams not to clash with those michael@0: // provided in native lib michael@0: # define cin _STLP_cin michael@0: # define cout _STLP_cout michael@0: # define cerr _STLP_cerr michael@0: # define clog _STLP_clog michael@0: #endif michael@0: michael@0: _STLP_BEGIN_NAMESPACE michael@0: michael@0: // This file handles iostream initialization. It is inherently michael@0: // nonportable, since the C++ language definition provides no mechanism michael@0: // for controlling order of initialization of nonlocal objects. michael@0: // Initialization has three parts, which must be performed in the following michael@0: // order: michael@0: // (1) Initialize the locale system michael@0: // (2) Call the constructors for the eight global stream objects. michael@0: // (3) Create streambufs for the global stream objects, and initialize michael@0: // the stream objects by calling the init() member function. michael@0: michael@0: michael@0: #if defined (_STLP_USE_NOT_INIT_SEGMENT) michael@0: michael@0: // Definitions of the eight global I/O objects that are declared in michael@0: // . For some compilers we use pragmas to put the global I/O michael@0: // objects into an initialization segment that will not michael@0: // be executed. We then explicitly invoke the constructors michael@0: // with placement new in ios_base::_S_initialize() michael@0: michael@0: # if defined (__MWERKS__) michael@0: # pragma suppress_init_code on michael@0: # else michael@0: # pragma init_seg("STLPORT_NO_INIT") michael@0: # endif michael@0: michael@0: _STLP_DECLSPEC istream cin(0); michael@0: _STLP_DECLSPEC ostream cout(0); michael@0: _STLP_DECLSPEC ostream cerr(0); michael@0: _STLP_DECLSPEC ostream clog(0); michael@0: michael@0: # ifndef _STLP_NO_WCHAR_T michael@0: _STLP_DECLSPEC wistream wcin(0); michael@0: _STLP_DECLSPEC wostream wcout(0); michael@0: _STLP_DECLSPEC wostream wcerr(0); michael@0: _STLP_DECLSPEC wostream wclog(0); michael@0: # endif michael@0: michael@0: # if defined (__MWERKS__) michael@0: # pragma suppress_init_code off michael@0: # endif michael@0: michael@0: #else michael@0: michael@0: // Definitions of the eight global I/O objects that are declared in michael@0: // . Disgusting hack: we deliberately define them with the michael@0: // wrong types so that the constructors don't get run automatically. michael@0: // We need special tricks to make sure that these objects are struct- michael@0: // aligned rather than byte-aligned. michael@0: michael@0: // This is not portable. Declaring a variable with different types in michael@0: // two translations units is "undefined", according to the C++ standard. michael@0: // Most compilers, however, silently accept this instead of diagnosing michael@0: // it as an error. michael@0: michael@0: # ifndef __DMC__ michael@0: _STLP_DECLSPEC _Stl_aligned_buffer cin; michael@0: _STLP_DECLSPEC _Stl_aligned_buffer cout; michael@0: _STLP_DECLSPEC _Stl_aligned_buffer cerr; michael@0: _STLP_DECLSPEC _Stl_aligned_buffer clog; michael@0: # else michael@0: _Stl_aligned_buffer cin; michael@0: _Stl_aligned_buffer cout; michael@0: _Stl_aligned_buffer cerr; michael@0: _Stl_aligned_buffer clog; michael@0: michael@0: # 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") michael@0: # 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") michael@0: # 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") michael@0: # 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") michael@0: # endif michael@0: michael@0: # ifndef _STLP_NO_WCHAR_T michael@0: michael@0: # ifndef __DMC__ michael@0: _STLP_DECLSPEC _Stl_aligned_buffer wcin; michael@0: _STLP_DECLSPEC _Stl_aligned_buffer wcout; michael@0: _STLP_DECLSPEC _Stl_aligned_buffer wcerr; michael@0: _STLP_DECLSPEC _Stl_aligned_buffer wclog; michael@0: # else michael@0: _Stl_aligned_buffer wcin; michael@0: _Stl_aligned_buffer wcout; michael@0: _Stl_aligned_buffer wcerr; michael@0: _Stl_aligned_buffer wclog; michael@0: michael@0: # 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") michael@0: # 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") michael@0: # 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") michael@0: # 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") michael@0: # endif michael@0: # endif michael@0: #endif /* STL_MSVC || __MWERKS__ */ michael@0: michael@0: // Member functions from class ios_base and ios_base::Init michael@0: michael@0: long ios_base::Init::_S_count = 0; michael@0: // by default, those are synced michael@0: bool ios_base::_S_is_synced = true; michael@0: michael@0: ios_base::Init::Init() { michael@0: if (_S_count++ == 0) { michael@0: _Locale_init(); michael@0: ios_base::_S_initialize(); michael@0: _Filebuf_base::_S_initialize(); michael@0: } michael@0: } michael@0: michael@0: ios_base::Init::~Init() { michael@0: if (--_S_count == 0) { michael@0: ios_base::_S_uninitialize(); michael@0: _Locale_final(); michael@0: } michael@0: } michael@0: michael@0: static int _Stl_extract_open_param(FILE* f) michael@0: { return _FILE_fd(f); } michael@0: michael@0: #ifdef _STLP_REDIRECT_STDSTREAMS michael@0: static const char* _Stl_extract_open_param(const char* name) michael@0: { return name; } michael@0: #endif michael@0: michael@0: template michael@0: static filebuf* michael@0: _Stl_create_filebuf(_Tp x, ios_base::openmode mode ) { michael@0: auto_ptr result(new basic_filebuf >()); michael@0: result->open(_Stl_extract_open_param(x), mode); michael@0: michael@0: if (result->is_open()) michael@0: return result.release(); michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: #if !defined (_STLP_NO_WCHAR_T) michael@0: static wfilebuf* michael@0: _Stl_create_wfilebuf(FILE* f, ios_base::openmode mode) { michael@0: auto_ptr result(new basic_filebuf >()); michael@0: result->_M_open(_FILE_fd(f), mode); michael@0: michael@0: if (result->is_open()) michael@0: return result.release(); michael@0: michael@0: return 0; michael@0: } michael@0: #endif michael@0: michael@0: void _STLP_CALL ios_base::_S_initialize() { michael@0: #if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE) michael@0: using _STLP_PRIV stdio_istreambuf; michael@0: using _STLP_PRIV stdio_ostreambuf; michael@0: #endif michael@0: michael@0: auto_ptr cin_buf; michael@0: auto_ptr cout_buf; michael@0: auto_ptr cerr_buf; michael@0: auto_ptr clog_buf; michael@0: michael@0: if (_S_is_synced) michael@0: cin_buf.reset(new stdio_istreambuf(stdin)); michael@0: else michael@0: cin_buf.reset(_Stl_create_filebuf(stdin, ios_base::in)); michael@0: michael@0: if (_S_is_synced) { michael@0: #ifdef _STLP_REDIRECT_STDSTREAMS michael@0: cout_buf.reset(_Stl_create_filebuf("/stdout.txt", ios::out)); michael@0: cerr_buf.reset(_Stl_create_filebuf("/stderr.txt", ios::out)); michael@0: clog_buf.reset(_Stl_create_filebuf("/stdlog.txt", ios::out)); michael@0: #else michael@0: cout_buf.reset(new stdio_ostreambuf(stdout)); michael@0: cerr_buf.reset(new stdio_ostreambuf(stderr)); michael@0: clog_buf.reset(new stdio_ostreambuf(stderr)); michael@0: #endif michael@0: } michael@0: else { michael@0: cout_buf.reset(_Stl_create_filebuf(stdout, ios_base::out)); michael@0: cerr_buf.reset(_Stl_create_filebuf(stderr, ios_base::out)); michael@0: clog_buf.reset(_Stl_create_filebuf(stderr, ios_base::out)); michael@0: } michael@0: michael@0: istream* ptr_cin = new(&cin) istream(cin_buf.get()); cin_buf.release(); michael@0: ostream* ptr_cout = new(&cout) ostream(cout_buf.get()); cout_buf.release(); michael@0: ostream* ptr_cerr = new(&cerr) ostream(cerr_buf.get()); cerr_buf.release(); michael@0: /*ostream* ptr_clog = */ new(&clog) ostream(clog_buf.get()); clog_buf.release(); michael@0: ptr_cin->tie(ptr_cout); michael@0: ptr_cerr->setf(ios_base::unitbuf); michael@0: michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: auto_ptr win(_Stl_create_wfilebuf(stdin, ios_base::in)); michael@0: auto_ptr wout(_Stl_create_wfilebuf(stdout, ios_base::out)); michael@0: auto_ptr werr(_Stl_create_wfilebuf(stderr, ios_base::out)); michael@0: auto_ptr wlog(_Stl_create_wfilebuf(stderr, ios_base::out)); michael@0: michael@0: // Run constructors for the four wide stream objects. michael@0: wistream* ptr_wcin = new(&wcin) wistream(win.get()); win.release(); michael@0: wostream* ptr_wcout = new(&wcout) wostream(wout.get()); wout.release(); michael@0: wostream* ptr_wcerr = new(&wcerr) wostream(werr.get()); werr.release(); michael@0: /*wostream* ptr_wclog = */ new(&wclog) wostream(wlog.get()); wlog.release(); michael@0: michael@0: ptr_wcin->tie(ptr_wcout); michael@0: ptr_wcerr->setf(ios_base::unitbuf); michael@0: #endif michael@0: } michael@0: michael@0: void _STLP_CALL ios_base::_S_uninitialize() { michael@0: // Note that destroying output streambufs flushes the buffers. michael@0: istream* ptr_cin = &cin; michael@0: ostream* ptr_cout = &cout; michael@0: ostream* ptr_cerr = &cerr; michael@0: ostream* ptr_clog = &clog; michael@0: michael@0: // We don't want any exceptions being thrown here michael@0: ptr_cin->exceptions(0); michael@0: ptr_cout->exceptions(0); michael@0: ptr_cerr->exceptions(0); michael@0: ptr_clog->exceptions(0); michael@0: michael@0: delete ptr_cin->rdbuf(0); michael@0: delete ptr_cout->rdbuf(0); michael@0: delete ptr_cerr->rdbuf(0); michael@0: delete ptr_clog->rdbuf(0); michael@0: michael@0: _Destroy(ptr_cin); michael@0: _Destroy(ptr_cout); michael@0: _Destroy(ptr_cerr); michael@0: _Destroy(ptr_clog); michael@0: michael@0: #ifndef _STLP_NO_WCHAR_T michael@0: wistream* ptr_wcin = &wcin; michael@0: wostream* ptr_wcout = &wcout; michael@0: wostream* ptr_wcerr = &wcerr; michael@0: wostream* ptr_wclog = &wclog; michael@0: michael@0: // We don't want any exceptions being thrown here michael@0: ptr_wcin->exceptions(0); michael@0: ptr_wcout->exceptions(0); michael@0: ptr_wcerr->exceptions(0); michael@0: ptr_wclog->exceptions(0); michael@0: michael@0: delete ptr_wcin->rdbuf(0); michael@0: delete ptr_wcout->rdbuf(0); michael@0: delete ptr_wcerr->rdbuf(0); michael@0: delete ptr_wclog->rdbuf(0); michael@0: michael@0: _Destroy(ptr_wcin); michael@0: _Destroy(ptr_wcout); michael@0: _Destroy(ptr_wcerr); michael@0: _Destroy(ptr_wclog); michael@0: #endif michael@0: } michael@0: michael@0: michael@0: bool _STLP_CALL ios_base::sync_with_stdio(bool sync) { michael@0: # if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE) michael@0: using _STLP_PRIV stdio_istreambuf; michael@0: using _STLP_PRIV stdio_ostreambuf; michael@0: # endif michael@0: michael@0: if (sync == _S_is_synced) return sync; michael@0: michael@0: // if by any chance we got there before std streams initialization, michael@0: // just set the sync flag and exit michael@0: if (Init::_S_count == 0) { michael@0: _S_is_synced = sync; michael@0: return sync; michael@0: } michael@0: michael@0: auto_ptr cin_buf; michael@0: auto_ptr cout_buf; michael@0: auto_ptr cerr_buf; michael@0: auto_ptr clog_buf; michael@0: michael@0: if (sync) michael@0: cin_buf.reset(new stdio_istreambuf(stdin)); michael@0: else michael@0: cin_buf.reset(_Stl_create_filebuf(stdin, ios_base::in)); michael@0: michael@0: if (sync) { michael@0: #ifdef _STLP_REDIRECT_STDSTREAMS michael@0: cout_buf.reset(_Stl_create_filebuf("/stdout.txt", ios::out)); michael@0: cerr_buf.reset(_Stl_create_filebuf("/stderr.txt", ios::out)); michael@0: clog_buf.reset(_Stl_create_filebuf("/stdlog.txt", ios::out)); michael@0: #else michael@0: cout_buf.reset(new stdio_ostreambuf(stdout)); michael@0: cerr_buf.reset(new stdio_ostreambuf(stderr)); michael@0: clog_buf.reset(new stdio_ostreambuf(stderr)); michael@0: #endif michael@0: } michael@0: else { michael@0: cout_buf.reset(_Stl_create_filebuf(stdout, ios_base::out)); michael@0: cerr_buf.reset(_Stl_create_filebuf(stderr, ios_base::out)); michael@0: clog_buf.reset(_Stl_create_filebuf(stderr, ios_base::out)); michael@0: } michael@0: michael@0: if (cin_buf.get() != 0 && cout_buf.get() != 0 && cerr_buf.get() != 0 && clog_buf.get() != 0) { michael@0: // When streambuf passed to rdbuf is not null, rdbuf is exception safe: michael@0: delete (&cin)->rdbuf(cin_buf.release()); michael@0: delete (&cout)->rdbuf(cout_buf.release()); michael@0: delete (&cerr)->rdbuf(cerr_buf.release()); michael@0: delete (&clog)->rdbuf(clog_buf.release()); michael@0: _S_is_synced = sync; michael@0: } michael@0: michael@0: return _S_is_synced; michael@0: } michael@0: michael@0: _STLP_END_NAMESPACE michael@0: michael@0: // Local Variables: michael@0: // mode:C++ michael@0: // End: