3 * Silicon Graphics Computer Systems, Inc.
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
11 * Permission to use or copy this software for any purpose is hereby granted
12 * without fee, provided the above notices are retained on all copies.
13 * Permission to modify the code and to distribute modified code is granted,
14 * provided the above notices are retained, and a notice that the code was
15 * modified is included with the above copyright notice.
18 #include "stlport_prefix.h"
22 #if defined (_STLP_MSVC) || defined (__MWERKS__) || defined (__ICL) || defined (__ISCPP__)
23 # define _STLP_USE_NOT_INIT_SEGMENT
27 #include "stdio_streambuf.h"
28 #include "aligned_buffer.h"
29 #include "_stdio_file.h"
32 // boris : note this is repeated in <iostream>
33 #ifndef _STLP_USE_NAMESPACES
34 // in case of SGI iostreams, we have to rename our streams not to clash with those
35 // provided in native lib
36 # define cin _STLP_cin
37 # define cout _STLP_cout
38 # define cerr _STLP_cerr
39 # define clog _STLP_clog
44 #if defined (__BORLANDC__) && ! defined (_STLP_USE_GLIBC)
45 using _STLP_VENDOR_CSTD::_streams;
48 // This file handles iostream initialization. It is inherently
49 // nonportable, since the C++ language definition provides no mechanism
50 // for controlling order of initialization of nonlocal objects.
51 // Initialization has three parts, which must be performed in the following
53 // (1) Initialize the locale system
54 // (2) Call the constructors for the eight global stream objects.
55 // (3) Create streambufs for the global stream objects, and initialize
56 // the stream objects by calling the init() member function.
59 #if defined (_STLP_USE_NOT_INIT_SEGMENT)
61 // Definitions of the eight global I/O objects that are declared in
62 // <iostream>. For some compilers we use pragmas to put the global I/O
63 // objects into an initialization segment that will not
64 // be executed. We then explicitly invoke the constructors
65 // with placement new in ios_base::_S_initialize()
67 # if defined (__MWERKS__)
68 # pragma suppress_init_code on
70 # pragma init_seg("STLPORT_NO_INIT")
73 _STLP_DECLSPEC istream cin(0);
75 # ifdef _STLP_REDIRECT_STDSTREAMS
76 _STLP_DECLSPEC ofstream cout;
77 _STLP_DECLSPEC ofstream cerr;
78 _STLP_DECLSPEC ofstream clog;
80 _STLP_DECLSPEC ostream cout(0);
81 _STLP_DECLSPEC ostream cerr(0);
82 _STLP_DECLSPEC ostream clog(0);
85 # ifndef _STLP_NO_WCHAR_T
86 _STLP_DECLSPEC wistream wcin(0);
87 _STLP_DECLSPEC wostream wcout(0);
88 _STLP_DECLSPEC wostream wcerr(0);
89 _STLP_DECLSPEC wostream wclog(0);
92 # if defined (__MWERKS__)
93 # pragma suppress_init_code off
98 // Definitions of the eight global I/O objects that are declared in
99 // <iostream>. Disgusting hack: we deliberately define them with the
100 // wrong types so that the constructors don't get run automatically.
101 // We need special tricks to make sure that these objects are struct-
102 // aligned rather than byte-aligned.
104 // This is not portable. Declaring a variable with different types in
105 // two translations units is "undefined", according to the C++ standard.
106 // Most compilers, however, silently accept this instead of diagnosing
110 _STLP_DECLSPEC _Stl_aligned_buffer<istream> cin;
111 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cout;
112 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cerr;
113 _STLP_DECLSPEC _Stl_aligned_buffer<ostream> clog;
115 _Stl_aligned_buffer<istream> cin;
116 _Stl_aligned_buffer<ostream> cout;
117 _Stl_aligned_buffer<ostream> cerr;
118 _Stl_aligned_buffer<ostream> clog;
120 # 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")
121 # 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")
122 # 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")
123 # 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")
126 # ifndef _STLP_NO_WCHAR_T
129 _STLP_DECLSPEC _Stl_aligned_buffer<wistream> wcin;
130 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcout;
131 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcerr;
132 _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wclog;
134 _Stl_aligned_buffer<wistream> wcin;
135 _Stl_aligned_buffer<wostream> wcout;
136 _Stl_aligned_buffer<wostream> wcerr;
137 _Stl_aligned_buffer<wostream> wclog;
139 # 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")
140 # 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")
141 # 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")
142 # 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")
145 #endif /* STL_MSVC || __MWERKS__ */
147 // Member functions from class ios_base and ios_base::Init
149 long ios_base::Init::_S_count = 0;
150 // by default, those are synced
151 bool ios_base::_S_was_synced = true;
153 ios_base::Init::Init() {
154 if (_S_count++ == 0) {
156 ios_base::_S_initialize();
157 _Filebuf_base::_S_initialize();
161 ios_base::Init::~Init() {
162 if (--_S_count == 0) {
163 ios_base::_S_uninitialize();
169 _Stl_create_filebuf(FILE* f, ios_base::openmode mode ) {
170 basic_filebuf<char, char_traits<char> >* result =
171 new basic_filebuf<char, char_traits<char> >();
174 result->_M_open(_FILE_fd(f), mode);
178 if (!result->is_open()) {
185 #if !defined (_STLP_NO_WCHAR_T)
187 _Stl_create_wfilebuf(FILE* f, ios_base::openmode mode) {
188 basic_filebuf<wchar_t, char_traits<wchar_t> >* result =
189 new basic_filebuf<wchar_t, char_traits<wchar_t> >();
192 result->_M_open(_FILE_fd(f), mode);
196 if (!result->is_open()) {
204 void _STLP_CALL ios_base::_S_initialize() {
205 #if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
206 using _STLP_PRIV stdio_istreambuf;
207 using _STLP_PRIV stdio_ostreambuf;
210 istream* ptr_cin = new(static_cast<void*>(&cin)) istream(0);
211 # ifdef _STLP_REDIRECT_STDSTREAMS
212 ofstream* ptr_cout = new(static_cast<void*>(&cout)) ofstream;
213 ofstream* ptr_cerr = new(static_cast<void*>(&cerr)) ofstream;
214 ofstream* ptr_clog = new(static_cast<void*>(&clog)) ofstream;
216 // Initialize the four narrow stream objects.
218 ptr_cin->init(new stdio_istreambuf(stdin));
219 ptr_cout->open("/stdout.txt", ios::out);
220 ptr_cerr->open("/stderr.txt", ios::out);
221 ptr_clog->open("/stdlog.txt", ios::out);
223 ptr_cin->init(_Stl_create_filebuf(stdin, ios_base::in));
224 ptr_cin->init(_Stl_create_filebuf(stdout, ios_base::out));
225 ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
226 ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
228 ptr_cin->tie(ptr_cout);
229 ptr_cerr->setf(ios_base::unitbuf);
231 ostream* ptr_cout = new(static_cast<void*>(&cout)) ostream(0);
232 ostream* ptr_cerr = new(static_cast<void*>(&cerr)) ostream(0);
233 ostream* ptr_clog = new(static_cast<void*>(&clog)) ostream(0);
235 // Initialize the four narrow stream objects.
237 ptr_cin->init(new stdio_istreambuf(stdin));
238 ptr_cout->init(new stdio_ostreambuf(stdout));
239 ptr_cerr->init(new stdio_ostreambuf(stderr));
240 ptr_clog->init(new stdio_ostreambuf(stderr));
242 ptr_cin->init(_Stl_create_filebuf(stdin, ios_base::in));
243 ptr_cin->init(_Stl_create_filebuf(stdout, ios_base::out));
244 ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
245 ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
247 ptr_cin->tie(ptr_cout);
248 ptr_cerr->setf(ios_base::unitbuf);
249 # endif /* _STLP_REDIRECT_STDSTREAMS */
251 # ifndef _STLP_NO_WCHAR_T
252 // Run constructors for the four wide stream objects.
253 wistream* ptr_wcin = new(&wcin) wistream(0);
254 wostream* ptr_wcout = new(&wcout) wostream(0);
255 wostream* ptr_wcerr = new(&wcerr) wostream(0);
256 wostream* ptr_wclog = new(&wclog) wostream(0);
258 wfilebuf* win = _Stl_create_wfilebuf(stdin, ios_base::in);
259 wfilebuf* wout = _Stl_create_wfilebuf(stdout, ios_base::out);
260 wfilebuf* werr = _Stl_create_wfilebuf(stderr, ios_base::out);
261 wfilebuf* wlog = _Stl_create_wfilebuf(stderr, ios_base::out);
264 ptr_wcout->init(wout);
265 ptr_wcerr->init(werr);
266 ptr_wclog->init(wlog);
268 ptr_wcin->tie(ptr_wcout);
269 ptr_wcerr->setf(ios_base::unitbuf);
271 # endif /* _STLP_NO_WCHAR_T */
277 void _STLP_CALL ios_base::_S_uninitialize() {
278 // Note that destroying output streambufs flushes the buffers.
280 istream* ptr_cin = &cin;
281 ostream* ptr_cout = &cout;
282 ostream* ptr_cerr = &cerr;
283 ostream* ptr_clog = &clog;
285 #ifndef _STLP_NO_WCHAR_T
286 wistream* ptr_wcin = &wcin;
287 wostream* ptr_wcout = &wcout;
288 wostream* ptr_wcerr = &wcerr;
289 wostream* ptr_wclog = &wclog;
292 // we don't want any exceptions being thrown here
293 ptr_cin->exceptions(0);
294 ptr_cout->exceptions(0);
295 ptr_cerr->exceptions(0);
296 ptr_clog->exceptions(0);
298 delete ptr_cin->rdbuf(0);
299 delete ptr_cout->rdbuf(0);
300 delete ptr_cerr->rdbuf(0);
301 delete ptr_clog->rdbuf(0);
308 #ifndef _STLP_NO_WCHAR_T
309 // we don't want any exceptions being thrown here
310 ptr_wcin->exceptions(0);
311 ptr_wcout->exceptions(0);
312 ptr_wcerr->exceptions(0);
313 ptr_wclog->exceptions(0);
315 delete ptr_wcin->rdbuf(0);
316 delete ptr_wcout->rdbuf(0);
317 delete ptr_wcerr->rdbuf(0);
318 delete ptr_wclog->rdbuf(0);
328 bool _STLP_CALL ios_base::sync_with_stdio(bool sync) {
329 # if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
330 using _STLP_PRIV stdio_istreambuf;
331 using _STLP_PRIV stdio_ostreambuf;
334 bool was_synced = _S_was_synced;
336 // if by any chance we got there before std streams initialization,
337 // just set the sync flag and exit
338 if (Init::_S_count == 0) {
339 _S_was_synced = sync;
343 istream* ptr_cin = &cin;
344 ostream* ptr_cout = &cout;
345 ostream* ptr_cerr = &cerr;
346 ostream* ptr_clog = &clog;
348 streambuf* old_cin = ptr_cin->rdbuf();
349 streambuf* old_cout = ptr_cout->rdbuf();
350 streambuf* old_cerr = ptr_cerr->rdbuf();
351 streambuf* old_clog = ptr_clog->rdbuf();
353 streambuf* new_cin = 0;
354 streambuf* new_cout = 0;
355 streambuf* new_cerr = 0;
356 streambuf* new_clog = 0;
359 if (sync && !was_synced) {
360 new_cin = new stdio_istreambuf(stdin);
361 new_cout = new stdio_ostreambuf(stdout);
362 new_cerr = new stdio_ostreambuf(stderr);
363 new_clog = new stdio_ostreambuf(stderr);
365 else if (!sync && was_synced) {
366 new_cin = _Stl_create_filebuf(stdin, ios_base::in);
367 new_cout = _Stl_create_filebuf(stdout, ios_base::out);
368 new_cerr = _Stl_create_filebuf(stderr, ios_base::out);
369 new_clog = _Stl_create_filebuf(stderr, ios_base::out);
374 if (new_cin && new_cout && new_cerr && new_clog) {
375 ptr_cin->rdbuf(new_cin);
376 ptr_cout->rdbuf(new_cout);
377 ptr_cerr->rdbuf(new_cerr);
378 ptr_clog->rdbuf(new_clog);