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"
23 #if defined (_STLP_MSVC) || defined (__MWERKS__) || defined (__ICL) || defined (__ISCPP__)
24 # define _STLP_USE_NOT_INIT_SEGMENT
28 #include "stdio_streambuf.h"
29 #include "aligned_buffer.h"
30 #include "_stdio_file.h"
33 // boris : note this is repeated in <iostream>
34 #ifndef _STLP_USE_NAMESPACES
35 // in case of SGI iostreams, we have to rename our streams not to clash with those
36 // provided in native lib
37 # define cin _STLP_cin
38 # define cout _STLP_cout
39 # define cerr _STLP_cerr
40 # define clog _STLP_clog
45 // This file handles iostream initialization. It is inherently
46 // nonportable, since the C++ language definition provides no mechanism
47 // for controlling order of initialization of nonlocal objects.
48 // Initialization has three parts, which must be performed in the following
50 // (1) Initialize the locale system
51 // (2) Call the constructors for the eight global stream objects.
52 // (3) Create streambufs for the global stream objects, and initialize
53 // the stream objects by calling the init() member function.
56 #if defined (_STLP_USE_NOT_INIT_SEGMENT)
58 // Definitions of the eight global I/O objects that are declared in
59 // <iostream>. For some compilers we use pragmas to put the global I/O
60 // objects into an initialization segment that will not
61 // be executed. We then explicitly invoke the constructors
62 // with placement new in ios_base::_S_initialize()
64 # if defined (__MWERKS__)
65 # pragma suppress_init_code on
67 # pragma init_seg("STLPORT_NO_INIT")
70 _STLP_DECLSPEC istream
cin(0);
71 _STLP_DECLSPEC ostream
cout(0);
72 _STLP_DECLSPEC ostream
cerr(0);
73 _STLP_DECLSPEC ostream
clog(0);
75 # ifndef _STLP_NO_WCHAR_T
76 _STLP_DECLSPEC wistream
wcin(0);
77 _STLP_DECLSPEC wostream
wcout(0);
78 _STLP_DECLSPEC wostream
wcerr(0);
79 _STLP_DECLSPEC wostream
wclog(0);
82 # if defined (__MWERKS__)
83 # pragma suppress_init_code off
88 // Definitions of the eight global I/O objects that are declared in
89 // <iostream>. Disgusting hack: we deliberately define them with the
90 // wrong types so that the constructors don't get run automatically.
91 // We need special tricks to make sure that these objects are struct-
92 // aligned rather than byte-aligned.
94 // This is not portable. Declaring a variable with different types in
95 // two translations units is "undefined", according to the C++ standard.
96 // Most compilers, however, silently accept this instead of diagnosing
100 _STLP_DECLSPEC _Stl_aligned_buffer
<istream
> cin
;
101 _STLP_DECLSPEC _Stl_aligned_buffer
<ostream
> cout
;
102 _STLP_DECLSPEC _Stl_aligned_buffer
<ostream
> cerr
;
103 _STLP_DECLSPEC _Stl_aligned_buffer
<ostream
> clog
;
105 _Stl_aligned_buffer
<istream
> cin
;
106 _Stl_aligned_buffer
<ostream
> cout
;
107 _Stl_aligned_buffer
<ostream
> cerr
;
108 _Stl_aligned_buffer
<ostream
> clog
;
110 # 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")
111 # 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")
112 # 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")
113 # 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")
116 # ifndef _STLP_NO_WCHAR_T
119 _STLP_DECLSPEC _Stl_aligned_buffer
<wistream
> wcin
;
120 _STLP_DECLSPEC _Stl_aligned_buffer
<wostream
> wcout
;
121 _STLP_DECLSPEC _Stl_aligned_buffer
<wostream
> wcerr
;
122 _STLP_DECLSPEC _Stl_aligned_buffer
<wostream
> wclog
;
124 _Stl_aligned_buffer
<wistream
> wcin
;
125 _Stl_aligned_buffer
<wostream
> wcout
;
126 _Stl_aligned_buffer
<wostream
> wcerr
;
127 _Stl_aligned_buffer
<wostream
> wclog
;
129 # 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")
130 # 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")
131 # 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")
132 # 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")
135 #endif /* STL_MSVC || __MWERKS__ */
137 // Member functions from class ios_base and ios_base::Init
139 long ios_base::Init::_S_count
= 0;
140 // by default, those are synced
141 bool ios_base::_S_is_synced
= true;
143 ios_base::Init::Init() {
144 if (_S_count
++ == 0) {
146 ios_base::_S_initialize();
147 _Filebuf_base::_S_initialize();
151 ios_base::Init::~Init() {
152 if (--_S_count
== 0) {
153 ios_base::_S_uninitialize();
158 static int _Stl_extract_open_param(FILE* f
)
159 { return _FILE_fd(f
); }
161 #ifdef _STLP_REDIRECT_STDSTREAMS
162 static const char* _Stl_extract_open_param(const char* name
)
168 _Stl_create_filebuf(_Tp x
, ios_base::openmode mode
) {
169 auto_ptr
<filebuf
> result(new basic_filebuf
<char, char_traits
<char> >());
170 result
->open(_Stl_extract_open_param(x
), mode
);
172 if (result
->is_open())
173 return result
.release();
178 #if !defined (_STLP_NO_WCHAR_T)
180 _Stl_create_wfilebuf(FILE* f
, ios_base::openmode mode
) {
181 auto_ptr
<wfilebuf
> result(new basic_filebuf
<wchar_t, char_traits
<wchar_t> >());
182 result
->_M_open(_FILE_fd(f
), mode
);
184 if (result
->is_open())
185 return result
.release();
191 void _STLP_CALL
ios_base::_S_initialize() {
192 #if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
193 using _STLP_PRIV stdio_istreambuf
;
194 using _STLP_PRIV stdio_ostreambuf
;
197 auto_ptr
<streambuf
> cin_buf
;
198 auto_ptr
<streambuf
> cout_buf
;
199 auto_ptr
<streambuf
> cerr_buf
;
200 auto_ptr
<streambuf
> clog_buf
;
203 cin_buf
.reset(new stdio_istreambuf(stdin
));
205 cin_buf
.reset(_Stl_create_filebuf(stdin
, ios_base::in
));
208 #ifdef _STLP_REDIRECT_STDSTREAMS
209 cout_buf
.reset(_Stl_create_filebuf("/stdout.txt", ios::out
));
210 cerr_buf
.reset(_Stl_create_filebuf("/stderr.txt", ios::out
));
211 clog_buf
.reset(_Stl_create_filebuf("/stdlog.txt", ios::out
));
213 cout_buf
.reset(new stdio_ostreambuf(stdout
));
214 cerr_buf
.reset(new stdio_ostreambuf(stderr
));
215 clog_buf
.reset(new stdio_ostreambuf(stderr
));
219 cout_buf
.reset(_Stl_create_filebuf(stdout
, ios_base::out
));
220 cerr_buf
.reset(_Stl_create_filebuf(stderr
, ios_base::out
));
221 clog_buf
.reset(_Stl_create_filebuf(stderr
, ios_base::out
));
224 istream
* ptr_cin
= new(&cin
) istream(cin_buf
.get()); cin_buf
.release();
225 ostream
* ptr_cout
= new(&cout
) ostream(cout_buf
.get()); cout_buf
.release();
226 ostream
* ptr_cerr
= new(&cerr
) ostream(cerr_buf
.get()); cerr_buf
.release();
227 /*ostream* ptr_clog = */ new(&clog
) ostream(clog_buf
.get()); clog_buf
.release();
228 ptr_cin
->tie(ptr_cout
);
229 ptr_cerr
->setf(ios_base::unitbuf
);
231 #ifndef _STLP_NO_WCHAR_T
232 auto_ptr
<wfilebuf
> win(_Stl_create_wfilebuf(stdin
, ios_base::in
));
233 auto_ptr
<wfilebuf
> wout(_Stl_create_wfilebuf(stdout
, ios_base::out
));
234 auto_ptr
<wfilebuf
> werr(_Stl_create_wfilebuf(stderr
, ios_base::out
));
235 auto_ptr
<wfilebuf
> wlog(_Stl_create_wfilebuf(stderr
, ios_base::out
));
237 // Run constructors for the four wide stream objects.
238 wistream
* ptr_wcin
= new(&wcin
) wistream(win
.get()); win
.release();
239 wostream
* ptr_wcout
= new(&wcout
) wostream(wout
.get()); wout
.release();
240 wostream
* ptr_wcerr
= new(&wcerr
) wostream(werr
.get()); werr
.release();
241 /*wostream* ptr_wclog = */ new(&wclog
) wostream(wlog
.get()); wlog
.release();
243 ptr_wcin
->tie(ptr_wcout
);
244 ptr_wcerr
->setf(ios_base::unitbuf
);
248 void _STLP_CALL
ios_base::_S_uninitialize() {
249 // Note that destroying output streambufs flushes the buffers.
250 istream
* ptr_cin
= &cin
;
251 ostream
* ptr_cout
= &cout
;
252 ostream
* ptr_cerr
= &cerr
;
253 ostream
* ptr_clog
= &clog
;
255 // We don't want any exceptions being thrown here
256 ptr_cin
->exceptions(0);
257 ptr_cout
->exceptions(0);
258 ptr_cerr
->exceptions(0);
259 ptr_clog
->exceptions(0);
261 delete ptr_cin
->rdbuf(0);
262 delete ptr_cout
->rdbuf(0);
263 delete ptr_cerr
->rdbuf(0);
264 delete ptr_clog
->rdbuf(0);
271 #ifndef _STLP_NO_WCHAR_T
272 wistream
* ptr_wcin
= &wcin
;
273 wostream
* ptr_wcout
= &wcout
;
274 wostream
* ptr_wcerr
= &wcerr
;
275 wostream
* ptr_wclog
= &wclog
;
277 // We don't want any exceptions being thrown here
278 ptr_wcin
->exceptions(0);
279 ptr_wcout
->exceptions(0);
280 ptr_wcerr
->exceptions(0);
281 ptr_wclog
->exceptions(0);
283 delete ptr_wcin
->rdbuf(0);
284 delete ptr_wcout
->rdbuf(0);
285 delete ptr_wcerr
->rdbuf(0);
286 delete ptr_wclog
->rdbuf(0);
296 bool _STLP_CALL
ios_base::sync_with_stdio(bool sync
) {
297 # if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
298 using _STLP_PRIV stdio_istreambuf
;
299 using _STLP_PRIV stdio_ostreambuf
;
302 if (sync
== _S_is_synced
) return sync
;
304 // if by any chance we got there before std streams initialization,
305 // just set the sync flag and exit
306 if (Init::_S_count
== 0) {
311 auto_ptr
<streambuf
> cin_buf
;
312 auto_ptr
<streambuf
> cout_buf
;
313 auto_ptr
<streambuf
> cerr_buf
;
314 auto_ptr
<streambuf
> clog_buf
;
317 cin_buf
.reset(new stdio_istreambuf(stdin
));
319 cin_buf
.reset(_Stl_create_filebuf(stdin
, ios_base::in
));
322 #ifdef _STLP_REDIRECT_STDSTREAMS
323 cout_buf
.reset(_Stl_create_filebuf("/stdout.txt", ios::out
));
324 cerr_buf
.reset(_Stl_create_filebuf("/stderr.txt", ios::out
));
325 clog_buf
.reset(_Stl_create_filebuf("/stdlog.txt", ios::out
));
327 cout_buf
.reset(new stdio_ostreambuf(stdout
));
328 cerr_buf
.reset(new stdio_ostreambuf(stderr
));
329 clog_buf
.reset(new stdio_ostreambuf(stderr
));
333 cout_buf
.reset(_Stl_create_filebuf(stdout
, ios_base::out
));
334 cerr_buf
.reset(_Stl_create_filebuf(stderr
, ios_base::out
));
335 clog_buf
.reset(_Stl_create_filebuf(stderr
, ios_base::out
));
338 if (cin_buf
.get() != 0 && cout_buf
.get() != 0 && cerr_buf
.get() != 0 && clog_buf
.get() != 0) {
339 // When streambuf passed to rdbuf is not null, rdbuf is exception safe:
340 delete (&cin
)->rdbuf(cin_buf
.release());
341 delete (&cout
)->rdbuf(cout_buf
.release());
342 delete (&cerr
)->rdbuf(cerr_buf
.release());
343 delete (&clog
)->rdbuf(clog_buf
.release());