]> git.buserror.net Git - polintos/scott/priv.git/blob - lib/c++/stlport/iostream.cpp
Random stuff.
[polintos/scott/priv.git] / lib / c++ / stlport / iostream.cpp
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 <istream>
21 #include <fstream>
22 #if defined (_STLP_MSVC) || defined (__MWERKS__) || defined (__ICL) || defined (__ISCPP__)
23 #  define _STLP_USE_NOT_INIT_SEGMENT
24 #  include <iostream>
25 #endif
26
27 #include "stdio_streambuf.h"
28 #include "aligned_buffer.h"
29 #include "_stdio_file.h"
30 #include "c_locale.h"
31
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
40 #endif
41
42 _STLP_BEGIN_NAMESPACE
43
44 #if defined (__BORLANDC__) && ! defined (_STLP_USE_GLIBC)
45 using _STLP_VENDOR_CSTD::_streams;
46 #endif
47
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
52 // order:
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.
57
58
59 #if defined (_STLP_USE_NOT_INIT_SEGMENT)
60
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()
66
67 #  if defined (__MWERKS__)
68 #    pragma suppress_init_code on
69 #  else
70 #    pragma init_seg("STLPORT_NO_INIT")
71 #  endif
72
73 _STLP_DECLSPEC istream cin(0);
74
75 #  ifdef _STLP_REDIRECT_STDSTREAMS
76 _STLP_DECLSPEC ofstream cout;
77 _STLP_DECLSPEC ofstream cerr;
78 _STLP_DECLSPEC ofstream clog;
79 #  else
80 _STLP_DECLSPEC ostream cout(0);
81 _STLP_DECLSPEC ostream cerr(0);
82 _STLP_DECLSPEC ostream clog(0);
83 #  endif
84
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);
90 #  endif
91
92 #  if defined (__MWERKS__)
93 #    pragma suppress_init_code off
94 #  endif
95
96 #else
97
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.
103
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
107 // it as an error.
108
109 #  ifndef __DMC__
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;
114 #  else
115 _Stl_aligned_buffer<istream> cin;
116 _Stl_aligned_buffer<ostream> cout;
117 _Stl_aligned_buffer<ostream> cerr;
118 _Stl_aligned_buffer<ostream> clog;
119
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")
124 #  endif
125
126 #  ifndef _STLP_NO_WCHAR_T
127
128 #    ifndef __DMC__
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;
133 #    else
134 _Stl_aligned_buffer<wistream> wcin;
135 _Stl_aligned_buffer<wostream> wcout;
136 _Stl_aligned_buffer<wostream> wcerr;
137 _Stl_aligned_buffer<wostream> wclog;
138
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")
143 #    endif
144 #  endif
145 #endif /* STL_MSVC || __MWERKS__ */
146
147 // Member functions from class ios_base and ios_base::Init
148
149 long ios_base::Init::_S_count = 0;
150 // by default, those are synced
151 bool ios_base::_S_was_synced = true;
152
153 ios_base::Init::Init() {
154   if (_S_count++ == 0) {
155     _Locale_init();
156     ios_base::_S_initialize();
157     _Filebuf_base::_S_initialize();
158   }
159 }
160
161 ios_base::Init::~Init() {
162   if (--_S_count == 0) {
163     ios_base::_S_uninitialize();
164     _Locale_final();
165   }
166 }
167
168 static filebuf*
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> >();
172
173   _STLP_TRY {
174     result->_M_open(_FILE_fd(f), mode);
175   }
176   _STLP_CATCH_ALL {}
177
178   if (!result->is_open()) {
179     delete result;
180     result = 0;
181   }
182   return result;
183 }
184
185 #if !defined (_STLP_NO_WCHAR_T)
186 static wfilebuf*
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> >();
190
191   _STLP_TRY {
192     result->_M_open(_FILE_fd(f), mode);
193   }
194   _STLP_CATCH_ALL {}
195
196   if (!result->is_open()) {
197     delete result;
198     result = 0;
199   }
200   return result;
201 }
202 #endif
203
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;
208 #endif
209   _STLP_TRY {
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;
215
216     // Initialize the four narrow stream objects.
217     if (_S_was_synced) {
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);
222     } else {
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));
227     }
228     ptr_cin->tie(ptr_cout);
229     ptr_cerr->setf(ios_base::unitbuf);
230 #  else
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);
234
235     // Initialize the four narrow stream objects.
236     if (_S_was_synced) {
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));
241     } else {
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));
246     }
247     ptr_cin->tie(ptr_cout);
248     ptr_cerr->setf(ios_base::unitbuf);
249 #  endif /* _STLP_REDIRECT_STDSTREAMS */
250
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);
257
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);
262
263     ptr_wcin->init(win);
264     ptr_wcout->init(wout);
265     ptr_wcerr->init(werr);
266     ptr_wclog->init(wlog);
267
268     ptr_wcin->tie(ptr_wcout);
269     ptr_wcerr->setf(ios_base::unitbuf);
270
271 #  endif /*  _STLP_NO_WCHAR_T */
272   }
273
274   _STLP_CATCH_ALL {}
275 }
276
277 void _STLP_CALL ios_base::_S_uninitialize() {
278   // Note that destroying output streambufs flushes the buffers.
279
280   istream* ptr_cin  = &cin;
281   ostream* ptr_cout = &cout;
282   ostream* ptr_cerr = &cerr;
283   ostream* ptr_clog = &clog;
284
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;
290 #endif
291
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);
297
298   delete ptr_cin->rdbuf(0);
299   delete ptr_cout->rdbuf(0);
300   delete ptr_cerr->rdbuf(0);
301   delete ptr_clog->rdbuf(0);
302
303   _Destroy(ptr_cin);
304   _Destroy(ptr_cout);
305   _Destroy(ptr_cerr);
306   _Destroy(ptr_clog);
307
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);
314
315   delete ptr_wcin->rdbuf(0);
316   delete ptr_wcout->rdbuf(0);
317   delete ptr_wcerr->rdbuf(0);
318   delete ptr_wclog->rdbuf(0);
319
320   _Destroy(ptr_wcin);
321   _Destroy(ptr_wcout);
322   _Destroy(ptr_wcerr);
323   _Destroy(ptr_wclog);
324 #endif
325 }
326
327
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;
332 #  endif
333
334   bool was_synced =  _S_was_synced;
335
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;
340     return was_synced;
341   }
342
343   istream* ptr_cin  = &cin;
344   ostream* ptr_cout = &cout;
345   ostream* ptr_cerr = &cerr;
346   ostream* ptr_clog = &clog;
347
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();
352
353   streambuf* new_cin  = 0;
354   streambuf* new_cout = 0;
355   streambuf* new_cerr = 0;
356   streambuf* new_clog = 0;
357
358   _STLP_TRY {
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);
364     }
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);
370     }
371   }
372   _STLP_CATCH_ALL {}
373
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);
379
380     delete old_cin;
381     delete old_cout;
382     delete old_cerr;
383     delete old_clog;
384   }
385   else {
386     delete new_cin;
387     delete new_cout;
388     delete new_cerr;
389     delete new_clog;
390   }
391
392   return was_synced;
393 }
394
395 _STLP_END_NAMESPACE
396
397 // Local Variables:
398 // mode:C++
399 // End: