source: trunk/gcc/libstdc++-v3/src/ios.cc

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 11.4 KB
Line 
1// Iostreams base classes -*- C++ -*-
2
3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library. This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16
17// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING. If not, write to the Free
19// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20// USA.
21
22// As a special exception, you may use this file as part of a free software
23// library without restriction. Specifically, if other files instantiate
24// templates or use macros or inline functions from this file, or you compile
25// this file and link it with other files to produce an executable, this
26// file does not by itself cause the resulting executable to be covered by
27// the GNU General Public License. This exception does not however
28// invalidate any other reasons why the executable file might be covered by
29// the GNU General Public License.
30
31//
32// ISO C++ 14882: 27.4 Iostreams base classes
33//
34
35#include <ios>
36#include <ostream>
37#include <istream>
38#include <fstream>
39#include <bits/atomicity.h>
40#include <ext/stdio_filebuf.h>
41#ifdef _GLIBCPP_HAVE_UNISTD_H
42#include <unistd.h>
43#endif
44
45namespace __gnu_cxx
46{
47 // Extern declarations for global objects in src/globals.cc.
48 extern stdio_filebuf<char> buf_cout;
49 extern stdio_filebuf<char> buf_cin;
50 extern stdio_filebuf<char> buf_cerr;
51
52#ifdef _GLIBCPP_USE_WCHAR_T
53 extern stdio_filebuf<wchar_t> buf_wcout;
54 extern stdio_filebuf<wchar_t> buf_wcin;
55 extern stdio_filebuf<wchar_t> buf_wcerr;
56#endif
57} // namespace __gnu_cxx
58
59namespace std
60{
61 using namespace __gnu_cxx;
62
63 extern istream cin;
64 extern ostream cout;
65 extern ostream cerr;
66 extern ostream clog;
67
68#ifdef _GLIBCPP_USE_WCHAR_T
69 extern wistream wcin;
70 extern wostream wcout;
71 extern wostream wcerr;
72 extern wostream wclog;
73#endif
74
75 // Definitions for static const data members of __ios_flags.
76 const __ios_flags::__int_type __ios_flags::_S_boolalpha;
77 const __ios_flags::__int_type __ios_flags::_S_dec;
78 const __ios_flags::__int_type __ios_flags::_S_fixed;
79 const __ios_flags::__int_type __ios_flags::_S_hex;
80 const __ios_flags::__int_type __ios_flags::_S_internal;
81 const __ios_flags::__int_type __ios_flags::_S_left;
82 const __ios_flags::__int_type __ios_flags::_S_oct;
83 const __ios_flags::__int_type __ios_flags::_S_right;
84 const __ios_flags::__int_type __ios_flags::_S_scientific;
85 const __ios_flags::__int_type __ios_flags::_S_showbase;
86 const __ios_flags::__int_type __ios_flags::_S_showpoint;
87 const __ios_flags::__int_type __ios_flags::_S_showpos;
88 const __ios_flags::__int_type __ios_flags::_S_skipws;
89 const __ios_flags::__int_type __ios_flags::_S_unitbuf;
90 const __ios_flags::__int_type __ios_flags::_S_uppercase;
91 const __ios_flags::__int_type __ios_flags::_S_adjustfield;
92 const __ios_flags::__int_type __ios_flags::_S_basefield;
93 const __ios_flags::__int_type __ios_flags::_S_floatfield;
94
95 const __ios_flags::__int_type __ios_flags::_S_badbit;
96 const __ios_flags::__int_type __ios_flags::_S_eofbit;
97 const __ios_flags::__int_type __ios_flags::_S_failbit;
98
99 const __ios_flags::__int_type __ios_flags::_S_app;
100 const __ios_flags::__int_type __ios_flags::_S_ate;
101 const __ios_flags::__int_type __ios_flags::_S_bin;
102 const __ios_flags::__int_type __ios_flags::_S_in;
103 const __ios_flags::__int_type __ios_flags::_S_out;
104 const __ios_flags::__int_type __ios_flags::_S_trunc;
105
106 // Definitions for static const members of ios_base.
107 const ios_base::fmtflags ios_base::boolalpha;
108 const ios_base::fmtflags ios_base::dec;
109 const ios_base::fmtflags ios_base::fixed;
110 const ios_base::fmtflags ios_base::hex;
111 const ios_base::fmtflags ios_base::internal;
112 const ios_base::fmtflags ios_base::left;
113 const ios_base::fmtflags ios_base::oct;
114 const ios_base::fmtflags ios_base::right;
115 const ios_base::fmtflags ios_base::scientific;
116 const ios_base::fmtflags ios_base::showbase;
117 const ios_base::fmtflags ios_base::showpoint;
118 const ios_base::fmtflags ios_base::showpos;
119 const ios_base::fmtflags ios_base::skipws;
120 const ios_base::fmtflags ios_base::unitbuf;
121 const ios_base::fmtflags ios_base::uppercase;
122 const ios_base::fmtflags ios_base::adjustfield;
123 const ios_base::fmtflags ios_base::basefield;
124 const ios_base::fmtflags ios_base::floatfield;
125
126 const ios_base::iostate ios_base::badbit;
127 const ios_base::iostate ios_base::eofbit;
128 const ios_base::iostate ios_base::failbit;
129 const ios_base::iostate ios_base::goodbit;
130
131 const ios_base::openmode ios_base::app;
132 const ios_base::openmode ios_base::ate;
133 const ios_base::openmode ios_base::binary;
134 const ios_base::openmode ios_base::in;
135 const ios_base::openmode ios_base::out;
136 const ios_base::openmode ios_base::trunc;
137
138 const ios_base::seekdir ios_base::beg;
139 const ios_base::seekdir ios_base::cur;
140 const ios_base::seekdir ios_base::end;
141
142 const int ios_base::_S_local_word_size;
143 int ios_base::Init::_S_ios_base_init = 0;
144 bool ios_base::Init::_S_synced_with_stdio = true;
145
146 ios_base::failure::failure(const string& __str) throw()
147 {
148 strncpy(_M_name, __str.c_str(), _M_bufsize);
149 _M_name[_M_bufsize - 1] = '\0';
150 }
151
152 ios_base::failure::~failure() throw()
153 { }
154
155 const char*
156 ios_base::failure::what() const throw()
157 { return _M_name; }
158
159 void
160 ios_base::Init::_S_ios_create(bool __sync)
161 {
162 size_t __out_size = __sync ? 0 : static_cast<size_t>(BUFSIZ);
163#ifdef _GLIBCPP_HAVE_ISATTY
164 size_t __in_size =
165 (__sync || isatty (0)) ? 1 : static_cast<size_t>(BUFSIZ);
166#else
167 size_t __in_size = 1;
168#endif
169
170 // NB: The file globals.cc creates the four standard files
171 // with NULL buffers. At this point, we swap out the dummy NULL
172 // [io]stream objects and buffers with the real deal.
173 new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out, __out_size);
174 new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in, __in_size);
175 new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out, __out_size);
176
177 new (&cout) ostream(&buf_cout);
178 new (&cin) istream(&buf_cin);
179 new (&cerr) ostream(&buf_cerr);
180 new (&clog) ostream(&buf_cerr);
181 cout.init(&buf_cout);
182 cin.init(&buf_cin);
183 cerr.init(&buf_cerr);
184 clog.init(&buf_cerr);
185 cin.tie(&cout);
186 cerr.flags(ios_base::unitbuf);
187
188#ifdef _GLIBCPP_USE_WCHAR_T
189 new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size);
190 new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in, __in_size);
191 new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size);
192 new (&wcout) wostream(&buf_wcout);
193 new (&wcin) wistream(&buf_wcin);
194 new (&wcerr) wostream(&buf_wcerr);
195 new (&wclog) wostream(&buf_wcerr);
196 wcout.init(&buf_wcout);
197 wcin.init(&buf_wcin);
198 wcerr.init(&buf_wcerr);
199 wclog.init(&buf_wcerr);
200 wcin.tie(&wcout);
201 wcerr.flags(ios_base::unitbuf);
202#endif
203 }
204
205 void
206 ios_base::Init::_S_ios_destroy()
207 {
208 // Explicitly call dtors to free any memory that is dynamically
209 // allocated by filebuf ctor or member functions, but don't
210 // deallocate all memory by calling operator delete.
211 buf_cout.~stdio_filebuf();
212 buf_cin.~stdio_filebuf();
213 buf_cerr.~stdio_filebuf();
214
215#ifdef _GLIBCPP_USE_WCHAR_T
216 buf_wcout.~stdio_filebuf();
217 buf_wcin.~stdio_filebuf();
218 buf_wcerr.~stdio_filebuf();
219#endif
220 }
221
222 ios_base::Init::Init()
223 {
224 if (_S_ios_base_init == 0)
225 {
226 // Standard streams default to synced with "C" operations.
227 ios_base::Init::_S_synced_with_stdio = true;
228 _S_ios_create(ios_base::Init::_S_synced_with_stdio);
229 }
230 ++_S_ios_base_init;
231 }
232
233 ios_base::Init::~Init()
234 {
235 if (--_S_ios_base_init == 0)
236 _S_ios_destroy();
237 }
238
239 // 27.4.2.5 ios_base storage functions
240 int
241 ios_base::xalloc() throw()
242 {
243 // Implementation note: Initialize top to zero to ensure that
244 // initialization occurs before main() is started.
245 static _Atomic_word _S_top = 0;
246 return __exchange_and_add(&_S_top, 1) + 4;
247 }
248
249 // 27.4.2.5 iword/pword storage
250 ios_base::_Words&
251 ios_base::_M_grow_words(int ix)
252 {
253 // Precondition: _M_word_size <= ix
254 int newsize = _S_local_word_size;
255 _Words* words = _M_local_word;
256 if (ix > _S_local_word_size - 1)
257 {
258 if (ix < numeric_limits<int>::max())
259 {
260 newsize = ix + 1;
261 try
262 { words = new _Words[newsize]; }
263 catch (...)
264 {
265 _M_streambuf_state |= badbit;
266 if (_M_streambuf_state & _M_exception)
267 __throw_ios_failure("ios_base::_M_grow_words failure");
268 return _M_word_zero;
269 }
270 for (int i = 0; i < _M_word_size; i++)
271 words[i] = _M_word[i];
272 if (_M_word && _M_word != _M_local_word)
273 {
274 delete [] _M_word;
275 _M_word = 0;
276 }
277 }
278 else
279 {
280 _M_streambuf_state |= badbit;
281 if (_M_streambuf_state & _M_exception)
282 __throw_ios_failure("ios_base::_M_grow_words failure");
283 return _M_word_zero;
284 }
285 }
286 _M_word = words;
287 _M_word_size = newsize;
288 return _M_word[ix];
289 }
290
291 // Called only by basic_ios<>::init.
292 void
293 ios_base::_M_init()
294 {
295 // NB: May be called more than once
296 _M_precision = 6;
297 _M_width = 0;
298 _M_flags = skipws | dec;
299 _M_ios_locale = locale();
300 }
301
302 // 27.4.2.3 ios_base locale functions
303 locale
304 ios_base::imbue(const locale& __loc)
305 {
306 locale __old = _M_ios_locale;
307 _M_ios_locale = __loc;
308 _M_call_callbacks(imbue_event);
309 return __old;
310 }
311
312 ios_base::ios_base() : _M_callbacks(0), _M_word_size(_S_local_word_size),
313 _M_word(_M_local_word)
314 {
315 // Do nothing: basic_ios::init() does it.
316 // NB: _M_callbacks and _M_word must be zero for non-initialized
317 // ios_base to go through ~ios_base gracefully.
318 }
319
320 // 27.4.2.7 ios_base constructors/destructors
321 ios_base::~ios_base()
322 {
323 _M_call_callbacks(erase_event);
324 _M_dispose_callbacks();
325 if (_M_word != _M_local_word)
326 {
327 delete [] _M_word;
328 _M_word = 0;
329 }
330 }
331
332 void
333 ios_base::register_callback(event_callback __fn, int __index)
334 { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); }
335
336 void
337 ios_base::_M_call_callbacks(event __e) throw()
338 {
339 _Callback_list* __p = _M_callbacks;
340 while (__p)
341 {
342 try
343 { (*__p->_M_fn) (__e, *this, __p->_M_index); }
344 catch (...)
345 { }
346 __p = __p->_M_next;
347 }
348 }
349
350 void
351 ios_base::_M_dispose_callbacks(void)
352 {
353 _Callback_list* __p = _M_callbacks;
354 while (__p && __p->_M_remove_reference() == 0)
355 {
356 _Callback_list* __next = __p->_M_next;
357 delete __p;
358 __p = __next;
359 }
360 _M_callbacks = 0;
361 }
362
363 bool
364 ios_base::sync_with_stdio(bool __sync)
365 {
366#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
367 // 49. Underspecification of ios_base::sync_with_stdio
368 bool __ret = ios_base::Init::_S_synced_with_stdio;
369#endif
370
371 // Turn off sync with C FILE* for cin, cout, cerr, clog iff
372 // currently synchronized.
373 if (!__sync && __ret)
374 {
375 ios_base::Init::_S_synced_with_stdio = false;
376 ios_base::Init::_S_ios_destroy();
377 ios_base::Init::_S_ios_create(ios_base::Init::_S_synced_with_stdio);
378 }
379 return __ret;
380 }
381} // namespace std
Note: See TracBrowser for help on using the repository browser.