|
1 /* |
|
2 * Copyright (c) 1999 |
|
3 * Silicon Graphics Computer Systems, Inc. |
|
4 * |
|
5 * Copyright (c) 1999 |
|
6 * Boris Fomitchev |
|
7 * |
|
8 * This material is provided "as is", with absolutely no warranty expressed |
|
9 * or implied. Any use is at your own risk. |
|
10 * |
|
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. |
|
16 * |
|
17 */ |
|
18 #include "stlport_prefix.h" |
|
19 |
|
20 #include <memory> |
|
21 #include <istream> |
|
22 #include <fstream> |
|
23 #if defined (_STLP_MSVC) || defined (__MWERKS__) || defined (__ICL) || defined (__ISCPP__) |
|
24 # define _STLP_USE_NOT_INIT_SEGMENT |
|
25 # include <iostream> |
|
26 #endif |
|
27 |
|
28 #include "stdio_streambuf.h" |
|
29 #include "aligned_buffer.h" |
|
30 #include "_stdio_file.h" |
|
31 #include "c_locale.h" |
|
32 |
|
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 |
|
41 #endif |
|
42 |
|
43 _STLP_BEGIN_NAMESPACE |
|
44 |
|
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 |
|
49 // order: |
|
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. |
|
54 |
|
55 |
|
56 #if defined (_STLP_USE_NOT_INIT_SEGMENT) |
|
57 |
|
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() |
|
63 |
|
64 # if defined (__MWERKS__) |
|
65 # pragma suppress_init_code on |
|
66 # else |
|
67 # pragma init_seg("STLPORT_NO_INIT") |
|
68 # endif |
|
69 |
|
70 _STLP_DECLSPEC istream cin(0); |
|
71 _STLP_DECLSPEC ostream cout(0); |
|
72 _STLP_DECLSPEC ostream cerr(0); |
|
73 _STLP_DECLSPEC ostream clog(0); |
|
74 |
|
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); |
|
80 # endif |
|
81 |
|
82 # if defined (__MWERKS__) |
|
83 # pragma suppress_init_code off |
|
84 # endif |
|
85 |
|
86 #else |
|
87 |
|
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. |
|
93 |
|
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 |
|
97 // it as an error. |
|
98 |
|
99 # ifndef __DMC__ |
|
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; |
|
104 # else |
|
105 _Stl_aligned_buffer<istream> cin; |
|
106 _Stl_aligned_buffer<ostream> cout; |
|
107 _Stl_aligned_buffer<ostream> cerr; |
|
108 _Stl_aligned_buffer<ostream> clog; |
|
109 |
|
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") |
|
114 # endif |
|
115 |
|
116 # ifndef _STLP_NO_WCHAR_T |
|
117 |
|
118 # ifndef __DMC__ |
|
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; |
|
123 # else |
|
124 _Stl_aligned_buffer<wistream> wcin; |
|
125 _Stl_aligned_buffer<wostream> wcout; |
|
126 _Stl_aligned_buffer<wostream> wcerr; |
|
127 _Stl_aligned_buffer<wostream> wclog; |
|
128 |
|
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") |
|
133 # endif |
|
134 # endif |
|
135 #endif /* STL_MSVC || __MWERKS__ */ |
|
136 |
|
137 // Member functions from class ios_base and ios_base::Init |
|
138 |
|
139 long ios_base::Init::_S_count = 0; |
|
140 // by default, those are synced |
|
141 bool ios_base::_S_is_synced = true; |
|
142 |
|
143 ios_base::Init::Init() { |
|
144 if (_S_count++ == 0) { |
|
145 _Locale_init(); |
|
146 ios_base::_S_initialize(); |
|
147 _Filebuf_base::_S_initialize(); |
|
148 } |
|
149 } |
|
150 |
|
151 ios_base::Init::~Init() { |
|
152 if (--_S_count == 0) { |
|
153 ios_base::_S_uninitialize(); |
|
154 _Locale_final(); |
|
155 } |
|
156 } |
|
157 |
|
158 static int _Stl_extract_open_param(FILE* f) |
|
159 { return _FILE_fd(f); } |
|
160 |
|
161 #ifdef _STLP_REDIRECT_STDSTREAMS |
|
162 static const char* _Stl_extract_open_param(const char* name) |
|
163 { return name; } |
|
164 #endif |
|
165 |
|
166 template <class _Tp> |
|
167 static filebuf* |
|
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); |
|
171 |
|
172 if (result->is_open()) |
|
173 return result.release(); |
|
174 |
|
175 return 0; |
|
176 } |
|
177 |
|
178 #if !defined (_STLP_NO_WCHAR_T) |
|
179 static wfilebuf* |
|
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); |
|
183 |
|
184 if (result->is_open()) |
|
185 return result.release(); |
|
186 |
|
187 return 0; |
|
188 } |
|
189 #endif |
|
190 |
|
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; |
|
195 #endif |
|
196 |
|
197 auto_ptr<streambuf> cin_buf; |
|
198 auto_ptr<streambuf> cout_buf; |
|
199 auto_ptr<streambuf> cerr_buf; |
|
200 auto_ptr<streambuf> clog_buf; |
|
201 |
|
202 if (_S_is_synced) |
|
203 cin_buf.reset(new stdio_istreambuf(stdin)); |
|
204 else |
|
205 cin_buf.reset(_Stl_create_filebuf(stdin, ios_base::in)); |
|
206 |
|
207 if (_S_is_synced) { |
|
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)); |
|
212 #else |
|
213 cout_buf.reset(new stdio_ostreambuf(stdout)); |
|
214 cerr_buf.reset(new stdio_ostreambuf(stderr)); |
|
215 clog_buf.reset(new stdio_ostreambuf(stderr)); |
|
216 #endif |
|
217 } |
|
218 else { |
|
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)); |
|
222 } |
|
223 |
|
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); |
|
230 |
|
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)); |
|
236 |
|
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(); |
|
242 |
|
243 ptr_wcin->tie(ptr_wcout); |
|
244 ptr_wcerr->setf(ios_base::unitbuf); |
|
245 #endif |
|
246 } |
|
247 |
|
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; |
|
254 |
|
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); |
|
260 |
|
261 delete ptr_cin->rdbuf(0); |
|
262 delete ptr_cout->rdbuf(0); |
|
263 delete ptr_cerr->rdbuf(0); |
|
264 delete ptr_clog->rdbuf(0); |
|
265 |
|
266 _Destroy(ptr_cin); |
|
267 _Destroy(ptr_cout); |
|
268 _Destroy(ptr_cerr); |
|
269 _Destroy(ptr_clog); |
|
270 |
|
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; |
|
276 |
|
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); |
|
282 |
|
283 delete ptr_wcin->rdbuf(0); |
|
284 delete ptr_wcout->rdbuf(0); |
|
285 delete ptr_wcerr->rdbuf(0); |
|
286 delete ptr_wclog->rdbuf(0); |
|
287 |
|
288 _Destroy(ptr_wcin); |
|
289 _Destroy(ptr_wcout); |
|
290 _Destroy(ptr_wcerr); |
|
291 _Destroy(ptr_wclog); |
|
292 #endif |
|
293 } |
|
294 |
|
295 |
|
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; |
|
300 # endif |
|
301 |
|
302 if (sync == _S_is_synced) return sync; |
|
303 |
|
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) { |
|
307 _S_is_synced = sync; |
|
308 return sync; |
|
309 } |
|
310 |
|
311 auto_ptr<streambuf> cin_buf; |
|
312 auto_ptr<streambuf> cout_buf; |
|
313 auto_ptr<streambuf> cerr_buf; |
|
314 auto_ptr<streambuf> clog_buf; |
|
315 |
|
316 if (sync) |
|
317 cin_buf.reset(new stdio_istreambuf(stdin)); |
|
318 else |
|
319 cin_buf.reset(_Stl_create_filebuf(stdin, ios_base::in)); |
|
320 |
|
321 if (sync) { |
|
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)); |
|
326 #else |
|
327 cout_buf.reset(new stdio_ostreambuf(stdout)); |
|
328 cerr_buf.reset(new stdio_ostreambuf(stderr)); |
|
329 clog_buf.reset(new stdio_ostreambuf(stderr)); |
|
330 #endif |
|
331 } |
|
332 else { |
|
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)); |
|
336 } |
|
337 |
|
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()); |
|
344 _S_is_synced = sync; |
|
345 } |
|
346 |
|
347 return _S_is_synced; |
|
348 } |
|
349 |
|
350 _STLP_END_NAMESPACE |
|
351 |
|
352 // Local Variables: |
|
353 // mode:C++ |
|
354 // End: |