2002-01-04 Benjamin Kosnik <bkoz@redhat.com>
[official-gcc.git] / libstdc++-v3 / src / ios.cc
blob6ca59572fba80b3a57e0d670e2ce8b72959ed377
1 // Iostreams base classes -*- C++ -*-
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
31 // ISO C++ 14882: 27.4 Iostreams base classes
34 #include <ios>
35 #include <ostream>
36 #include <istream>
37 #include <fstream>
39 namespace std
41 // Extern declarations for global objects in src/globals.cc.
42 extern istream cin;
43 extern ostream cout;
44 extern ostream cerr;
45 extern ostream clog;
46 extern filebuf buf_cout;
47 extern filebuf buf_cin;
48 extern filebuf buf_cerr;
50 #ifdef _GLIBCPP_USE_WCHAR_T
51 extern wistream wcin;
52 extern wostream wcout;
53 extern wostream wcerr;
54 extern wostream wclog;
55 extern wfilebuf buf_wcout;
56 extern wfilebuf buf_wcin;
57 extern wfilebuf buf_wcerr;
58 #endif
60 // Definitions for static const data members of __ios_flags.
61 const __ios_flags::__int_type __ios_flags::_S_boolalpha;
62 const __ios_flags::__int_type __ios_flags::_S_dec;
63 const __ios_flags::__int_type __ios_flags::_S_fixed;
64 const __ios_flags::__int_type __ios_flags::_S_hex;
65 const __ios_flags::__int_type __ios_flags::_S_internal;
66 const __ios_flags::__int_type __ios_flags::_S_left;
67 const __ios_flags::__int_type __ios_flags::_S_oct;
68 const __ios_flags::__int_type __ios_flags::_S_right;
69 const __ios_flags::__int_type __ios_flags::_S_scientific;
70 const __ios_flags::__int_type __ios_flags::_S_showbase;
71 const __ios_flags::__int_type __ios_flags::_S_showpoint;
72 const __ios_flags::__int_type __ios_flags::_S_showpos;
73 const __ios_flags::__int_type __ios_flags::_S_skipws;
74 const __ios_flags::__int_type __ios_flags::_S_unitbuf;
75 const __ios_flags::__int_type __ios_flags::_S_uppercase;
76 const __ios_flags::__int_type __ios_flags::_S_adjustfield;
77 const __ios_flags::__int_type __ios_flags::_S_basefield;
78 const __ios_flags::__int_type __ios_flags::_S_floatfield;
80 const __ios_flags::__int_type __ios_flags::_S_badbit;
81 const __ios_flags::__int_type __ios_flags::_S_eofbit;
82 const __ios_flags::__int_type __ios_flags::_S_failbit;
84 const __ios_flags::__int_type __ios_flags::_S_app;
85 const __ios_flags::__int_type __ios_flags::_S_ate;
86 const __ios_flags::__int_type __ios_flags::_S_bin;
87 const __ios_flags::__int_type __ios_flags::_S_in;
88 const __ios_flags::__int_type __ios_flags::_S_out;
89 const __ios_flags::__int_type __ios_flags::_S_trunc;
91 // Definitions for static const members of ios_base.
92 const ios_base::fmtflags ios_base::boolalpha;
93 const ios_base::fmtflags ios_base::dec;
94 const ios_base::fmtflags ios_base::fixed;
95 const ios_base::fmtflags ios_base::hex;
96 const ios_base::fmtflags ios_base::internal;
97 const ios_base::fmtflags ios_base::left;
98 const ios_base::fmtflags ios_base::oct;
99 const ios_base::fmtflags ios_base::right;
100 const ios_base::fmtflags ios_base::scientific;
101 const ios_base::fmtflags ios_base::showbase;
102 const ios_base::fmtflags ios_base::showpoint;
103 const ios_base::fmtflags ios_base::showpos;
104 const ios_base::fmtflags ios_base::skipws;
105 const ios_base::fmtflags ios_base::unitbuf;
106 const ios_base::fmtflags ios_base::uppercase;
107 const ios_base::fmtflags ios_base::adjustfield;
108 const ios_base::fmtflags ios_base::basefield;
109 const ios_base::fmtflags ios_base::floatfield;
111 const ios_base::iostate ios_base::badbit;
112 const ios_base::iostate ios_base::eofbit;
113 const ios_base::iostate ios_base::failbit;
114 const ios_base::iostate ios_base::goodbit;
116 const ios_base::openmode ios_base::app;
117 const ios_base::openmode ios_base::ate;
118 const ios_base::openmode ios_base::binary;
119 const ios_base::openmode ios_base::in;
120 const ios_base::openmode ios_base::out;
121 const ios_base::openmode ios_base::trunc;
123 const ios_base::seekdir ios_base::beg;
124 const ios_base::seekdir ios_base::cur;
125 const ios_base::seekdir ios_base::end;
127 const int ios_base::_S_local_words;
128 int ios_base::Init::_S_ios_base_init = 0;
129 bool ios_base::Init::_S_synced_with_stdio = true;
131 ios_base::failure::failure(const string& __str) throw()
133 strncpy(_M_name, __str.c_str(), _M_bufsize);
134 _M_name[_M_bufsize - 1] = '\0';
137 ios_base::failure::~failure() throw()
140 const char*
141 ios_base::failure::what() const throw()
142 { return _M_name; }
144 void
145 ios_base::Init::_S_ios_create(bool __sync)
147 int __out_bufsize = __sync ? 0 : static_cast<int>(BUFSIZ);
148 int __in_bufsize = __sync ? 1 : static_cast<int>(BUFSIZ);
150 #if _GLIBCPP_AVOID_FSEEK
151 // Platforms that prefer to avoid fseek() calls on streams only
152 // get their desire when the C++-layer input buffer size is 1.
153 // This hack hurts performance but keeps correctness across
154 // all types of streams that might be attached to (e.g.) cin.
155 __in_bufsize = 1;
156 #endif
158 // NB: The file globals.cc creates the four standard files
159 // with NULL buffers. At this point, we swap out the dummy NULL
160 // [io]stream objects and buffers with the real deal.
161 new (&buf_cout) filebuf(stdout, ios_base::out, __out_bufsize);
162 new (&buf_cin) filebuf(stdin, ios_base::in, __in_bufsize);
163 new (&buf_cerr) filebuf(stderr, ios_base::out, __out_bufsize);
164 new (&cout) ostream(&buf_cout);
165 new (&cin) istream(&buf_cin);
166 new (&cerr) ostream(&buf_cerr);
167 new (&clog) ostream(&buf_cerr);
168 cin.tie(&cout);
169 cerr.flags(ios_base::unitbuf);
171 #ifdef _GLIBCPP_USE_WCHAR_T
172 new (&buf_wcout) wfilebuf(stdout, ios_base::out, __out_bufsize);
173 new (&buf_wcin) wfilebuf(stdin, ios_base::in, __in_bufsize);
174 new (&buf_wcerr) wfilebuf(stderr, ios_base::out, __out_bufsize);
175 new (&wcout) wostream(&buf_wcout);
176 new (&wcin) wistream(&buf_wcin);
177 new (&wcerr) wostream(&buf_wcerr);
178 new (&wclog) wostream(&buf_wcerr);
179 wcin.tie(&wcout);
180 wcerr.flags(ios_base::unitbuf);
181 #endif
184 void
185 ios_base::Init::_S_ios_destroy()
187 // Explicitly call dtors to free any memory that is dynamically
188 // allocated by filebuf ctor or member functions, but don't
189 // deallocate all memory by calling operator delete.
190 cout.flush();
191 cerr.flush();
192 clog.flush();
193 buf_cout.~filebuf();
194 buf_cin.~filebuf();
195 buf_cerr.~filebuf();
196 #ifdef _GLIBCPP_USE_WCHAR_T
197 wcout.flush();
198 wcerr.flush();
199 wclog.flush();
200 buf_wcout.~wfilebuf();
201 buf_wcin.~wfilebuf();
202 buf_wcerr.~wfilebuf();
203 #endif
206 ios_base::Init::Init()
208 if (_S_ios_base_init == 0)
210 // Standard streams default to synced with "C" operations.
211 ios_base::Init::_S_synced_with_stdio = true;
212 _S_ios_create(ios_base::Init::_S_synced_with_stdio);
214 ++_S_ios_base_init;
217 ios_base::Init::~Init()
219 if (--_S_ios_base_init == 0)
220 _S_ios_destroy();
223 // 27.4.2.5 ios_base storage functions
224 int
225 ios_base::xalloc() throw()
227 // XXX MT
228 // XXX should be a symbol. (Reserve 0..3 for builtins.)
229 static int top = 4;
230 return top++;
233 // 27.4.2.5 iword/pword storage
234 ios_base::_Words&
235 ios_base::_M_grow_words(int ix)
237 // Precondition: _M_word_limit <= ix
238 _Words zero = { 0, 0 };
239 int newlimit = _S_local_words;
240 _Words* words = _M_word_array;
241 int i = 0;
242 if (_S_local_words <= ix)
244 newlimit = ix+1;
246 { words = new _Words[ix+1]; }
247 catch (...)
249 _M_dummy = zero; // XXX MT? Not on "normal" machines.
250 // XXX now in basic_ios
251 // _M_clear(_M_rdstate() | badbit); // may throw
252 return _M_dummy;
254 for (; i < _M_word_limit; i++)
255 words[i] = _M_words[i];
256 if (_M_words != _M_word_array)
257 delete [] _M_words;
260 do { words[i] = zero; } while (++i < newlimit);
261 _M_words = words;
262 _M_word_limit = newlimit;
263 return words[ix];
266 // Called only by basic_ios<>::init.
267 void
268 ios_base::_M_init()
270 // NB: May be called more than once
271 _M_precision = 6;
272 _M_width = 0;
273 _M_flags = skipws | dec;
274 _M_callbacks = 0;
275 _M_words = 0;
276 _M_word_limit = 0;
277 _M_ios_locale = locale();
278 // No init needed for _M_word_array or _M_dummy.
281 // 27.4.2.3 ios_base locale functions
282 locale
283 ios_base::imbue(const locale& __loc)
285 locale __old = _M_ios_locale;
286 _M_ios_locale = __loc;
287 _M_call_callbacks(imbue_event);
288 return __old;
291 ios_base::ios_base()
293 // Do nothing; init() does it. Static init to 0 makes everything sane.
296 // 27.4.2.7 ios_base constructors/destructors
297 ios_base::~ios_base()
299 _M_call_callbacks(erase_event);
300 _M_dispose_callbacks();
301 if (_M_words != _M_word_array)
302 delete [] _M_words;
303 // XXX done?
306 void
307 ios_base::register_callback(event_callback __fn, int __index)
308 { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); }
310 void
311 ios_base::_M_call_callbacks(event __e) throw()
313 for (_Callback_list* __p = _M_callbacks; __p; __p = __p->_M_next)
315 try {
316 (*__p->_M_fn) (__e, *this, __p->_M_index);
318 catch (...) {
323 void
324 ios_base::_M_dispose_callbacks(void)
326 _Callback_list* __p = _M_callbacks;
327 while (__p && __p->_M_remove_reference() == 0)
329 _Callback_list* __next = __p->_M_next;
330 delete __p;
331 __p = __next;
333 _M_callbacks = 0;
336 bool
337 ios_base::sync_with_stdio(bool __sync)
339 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
340 // 49. Underspecification of ios_base::sync_with_stdio
341 bool __ret = ios_base::Init::_S_synced_with_stdio;
342 #endif
344 // Turn off sync with C FILE* for cin, cout, cerr, clog iff
345 // currently synchronized.
346 if (!__sync && __ret)
348 ios_base::Init::_S_synced_with_stdio = false;
349 ios_base::Init::_S_ios_destroy();
350 ios_base::Init::_S_ios_create(ios_base::Init::_S_synced_with_stdio);
352 return __ret;
354 } // namespace std