ios.cc revision 97403
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 42namespace std 43{ 44 // Extern declarations for global objects in src/globals.cc. 45 extern istream cin; 46 extern ostream cout; 47 extern ostream cerr; 48 extern ostream clog; 49 50 using __gnu_cxx::stdio_filebuf; 51 extern stdio_filebuf<char> buf_cout; 52 extern stdio_filebuf<char> buf_cin; 53 extern stdio_filebuf<char> buf_cerr; 54 55#ifdef _GLIBCPP_USE_WCHAR_T 56 extern wistream wcin; 57 extern wostream wcout; 58 extern wostream wcerr; 59 extern wostream wclog; 60 61 extern stdio_filebuf<wchar_t> buf_wcout; 62 extern stdio_filebuf<wchar_t> buf_wcin; 63 extern stdio_filebuf<wchar_t> buf_wcerr; 64#endif 65 66 // Definitions for static const data members of __ios_flags. 67 const __ios_flags::__int_type __ios_flags::_S_boolalpha; 68 const __ios_flags::__int_type __ios_flags::_S_dec; 69 const __ios_flags::__int_type __ios_flags::_S_fixed; 70 const __ios_flags::__int_type __ios_flags::_S_hex; 71 const __ios_flags::__int_type __ios_flags::_S_internal; 72 const __ios_flags::__int_type __ios_flags::_S_left; 73 const __ios_flags::__int_type __ios_flags::_S_oct; 74 const __ios_flags::__int_type __ios_flags::_S_right; 75 const __ios_flags::__int_type __ios_flags::_S_scientific; 76 const __ios_flags::__int_type __ios_flags::_S_showbase; 77 const __ios_flags::__int_type __ios_flags::_S_showpoint; 78 const __ios_flags::__int_type __ios_flags::_S_showpos; 79 const __ios_flags::__int_type __ios_flags::_S_skipws; 80 const __ios_flags::__int_type __ios_flags::_S_unitbuf; 81 const __ios_flags::__int_type __ios_flags::_S_uppercase; 82 const __ios_flags::__int_type __ios_flags::_S_adjustfield; 83 const __ios_flags::__int_type __ios_flags::_S_basefield; 84 const __ios_flags::__int_type __ios_flags::_S_floatfield; 85 86 const __ios_flags::__int_type __ios_flags::_S_badbit; 87 const __ios_flags::__int_type __ios_flags::_S_eofbit; 88 const __ios_flags::__int_type __ios_flags::_S_failbit; 89 90 const __ios_flags::__int_type __ios_flags::_S_app; 91 const __ios_flags::__int_type __ios_flags::_S_ate; 92 const __ios_flags::__int_type __ios_flags::_S_bin; 93 const __ios_flags::__int_type __ios_flags::_S_in; 94 const __ios_flags::__int_type __ios_flags::_S_out; 95 const __ios_flags::__int_type __ios_flags::_S_trunc; 96 97 // Definitions for static const members of ios_base. 98 const ios_base::fmtflags ios_base::boolalpha; 99 const ios_base::fmtflags ios_base::dec; 100 const ios_base::fmtflags ios_base::fixed; 101 const ios_base::fmtflags ios_base::hex; 102 const ios_base::fmtflags ios_base::internal; 103 const ios_base::fmtflags ios_base::left; 104 const ios_base::fmtflags ios_base::oct; 105 const ios_base::fmtflags ios_base::right; 106 const ios_base::fmtflags ios_base::scientific; 107 const ios_base::fmtflags ios_base::showbase; 108 const ios_base::fmtflags ios_base::showpoint; 109 const ios_base::fmtflags ios_base::showpos; 110 const ios_base::fmtflags ios_base::skipws; 111 const ios_base::fmtflags ios_base::unitbuf; 112 const ios_base::fmtflags ios_base::uppercase; 113 const ios_base::fmtflags ios_base::adjustfield; 114 const ios_base::fmtflags ios_base::basefield; 115 const ios_base::fmtflags ios_base::floatfield; 116 117 const ios_base::iostate ios_base::badbit; 118 const ios_base::iostate ios_base::eofbit; 119 const ios_base::iostate ios_base::failbit; 120 const ios_base::iostate ios_base::goodbit; 121 122 const ios_base::openmode ios_base::app; 123 const ios_base::openmode ios_base::ate; 124 const ios_base::openmode ios_base::binary; 125 const ios_base::openmode ios_base::in; 126 const ios_base::openmode ios_base::out; 127 const ios_base::openmode ios_base::trunc; 128 129 const ios_base::seekdir ios_base::beg; 130 const ios_base::seekdir ios_base::cur; 131 const ios_base::seekdir ios_base::end; 132 133 const int ios_base::_S_local_word_size; 134 int ios_base::Init::_S_ios_base_init = 0; 135 bool ios_base::Init::_S_synced_with_stdio = true; 136 137 ios_base::failure::failure(const string& __str) throw() 138 { 139 strncpy(_M_name, __str.c_str(), _M_bufsize); 140 _M_name[_M_bufsize - 1] = '\0'; 141 } 142 143 ios_base::failure::~failure() throw() 144 { } 145 146 const char* 147 ios_base::failure::what() const throw() 148 { return _M_name; } 149 150 void 151 ios_base::Init::_S_ios_create(bool __sync) 152 { 153 int __out_size = __sync ? 0 : static_cast<int>(BUFSIZ); 154 int __in_size = __sync ? 1 : static_cast<int>(BUFSIZ); 155 156 // NB: The file globals.cc creates the four standard files 157 // with NULL buffers. At this point, we swap out the dummy NULL 158 // [io]stream objects and buffers with the real deal. 159 new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out, __out_size); 160 new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in, __in_size); 161 new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out, __out_size); 162 new (&cout) ostream(&buf_cout); 163 new (&cin) istream(&buf_cin); 164 new (&cerr) ostream(&buf_cerr); 165 new (&clog) ostream(&buf_cerr); 166 cin.tie(&cout); 167 cerr.flags(ios_base::unitbuf); 168 169#ifdef _GLIBCPP_USE_WCHAR_T 170 new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size); 171 new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in, __in_size); 172 new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size); 173 new (&wcout) wostream(&buf_wcout); 174 new (&wcin) wistream(&buf_wcin); 175 new (&wcerr) wostream(&buf_wcerr); 176 new (&wclog) wostream(&buf_wcerr); 177 wcin.tie(&wcout); 178 wcerr.flags(ios_base::unitbuf); 179#endif 180 } 181 182 void 183 ios_base::Init::_S_ios_destroy() 184 { 185 // Explicitly call dtors to free any memory that is dynamically 186 // allocated by filebuf ctor or member functions, but don't 187 // deallocate all memory by calling operator delete. 188 buf_cout.~stdio_filebuf(); 189 buf_cin.~stdio_filebuf(); 190 buf_cerr.~stdio_filebuf(); 191 192#ifdef _GLIBCPP_USE_WCHAR_T 193 buf_wcout.~stdio_filebuf(); 194 buf_wcin.~stdio_filebuf(); 195 buf_wcerr.~stdio_filebuf(); 196#endif 197 } 198 199 ios_base::Init::Init() 200 { 201 if (_S_ios_base_init == 0) 202 { 203 // Standard streams default to synced with "C" operations. 204 ios_base::Init::_S_synced_with_stdio = true; 205 _S_ios_create(ios_base::Init::_S_synced_with_stdio); 206 } 207 ++_S_ios_base_init; 208 } 209 210 ios_base::Init::~Init() 211 { 212 if (--_S_ios_base_init == 0) 213 _S_ios_destroy(); 214 } 215 216 // 27.4.2.5 ios_base storage functions 217 int 218 ios_base::xalloc() throw() 219 { 220 // Implementation note: Initialize top to zero to ensure that 221 // initialization occurs before main() is started. 222 static _Atomic_word _S_top = 0; 223 return __exchange_and_add(&_S_top, 1) + 4; 224 } 225 226 // 27.4.2.5 iword/pword storage 227 ios_base::_Words& 228 ios_base::_M_grow_words(int ix) 229 { 230 // Precondition: _M_word_size <= ix 231 int newsize = _S_local_word_size; 232 _Words* words = _M_local_word; 233 if (ix > _S_local_word_size - 1) 234 { 235 if (ix < numeric_limits<int>::max()) 236 { 237 newsize = ix + 1; 238 try 239 { words = new _Words[newsize]; } 240 catch (...) 241 { 242 delete [] _M_word; 243 _M_word = 0; 244 _M_streambuf_state |= badbit; 245 if (_M_streambuf_state & _M_exception) 246 __throw_ios_failure("ios_base::_M_grow_words failure"); 247 return _M_word_zero; 248 } 249 for (int i = 0; i < _M_word_size; i++) 250 words[i] = _M_word[i]; 251 if (_M_word && _M_word != _M_local_word) 252 { 253 delete [] _M_word; 254 _M_word = 0; 255 } 256 } 257 else 258 { 259 _M_streambuf_state |= badbit; 260 return _M_word_zero; 261 } 262 } 263 _M_word = words; 264 _M_word_size = newsize; 265 return _M_word[ix]; 266 } 267 268 // Called only by basic_ios<>::init. 269 void 270 ios_base::_M_init() 271 { 272 // NB: May be called more than once 273 _M_precision = 6; 274 _M_width = 0; 275 _M_flags = skipws | dec; 276 _M_callbacks = 0; 277 _M_word_size = 0; 278 _M_ios_locale = locale(); 279 } 280 281 // 27.4.2.3 ios_base locale functions 282 locale 283 ios_base::imbue(const locale& __loc) 284 { 285 locale __old = _M_ios_locale; 286 _M_ios_locale = __loc; 287 _M_call_callbacks(imbue_event); 288 return __old; 289 } 290 291 ios_base::ios_base() : _M_callbacks(0), _M_word(0) 292 { 293 // Do nothing: basic_ios::init() does it. 294 // NB: _M_callbacks and _M_word must be zero for non-initialized 295 // ios_base to go through ~ios_base gracefully. 296 } 297 298 // 27.4.2.7 ios_base constructors/destructors 299 ios_base::~ios_base() 300 { 301 _M_call_callbacks(erase_event); 302 _M_dispose_callbacks(); 303 if (_M_word && _M_word != _M_local_word) 304 { 305 delete [] _M_word; 306 _M_word = 0; 307 } 308 } 309 310 void 311 ios_base::register_callback(event_callback __fn, int __index) 312 { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); } 313 314 void 315 ios_base::_M_call_callbacks(event __e) throw() 316 { 317 _Callback_list* __p = _M_callbacks; 318 while (__p) 319 { 320 try 321 { (*__p->_M_fn) (__e, *this, __p->_M_index); } 322 catch (...) 323 { } 324 __p = __p->_M_next; 325 } 326 } 327 328 void 329 ios_base::_M_dispose_callbacks(void) 330 { 331 _Callback_list* __p = _M_callbacks; 332 while (__p && __p->_M_remove_reference() == 0) 333 { 334 _Callback_list* __next = __p->_M_next; 335 delete __p; 336 __p = __next; 337 } 338 _M_callbacks = 0; 339 } 340 341 bool 342 ios_base::sync_with_stdio(bool __sync) 343 { 344#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 345 // 49. Underspecification of ios_base::sync_with_stdio 346 bool __ret = ios_base::Init::_S_synced_with_stdio; 347#endif 348 349 // Turn off sync with C FILE* for cin, cout, cerr, clog iff 350 // currently synchronized. 351 if (!__sync && __ret) 352 { 353 ios_base::Init::_S_synced_with_stdio = false; 354 ios_base::Init::_S_ios_destroy(); 355 ios_base::Init::_S_ios_create(ios_base::Init::_S_synced_with_stdio); 356 } 357 return __ret; 358 } 359} // namespace std 360