103a78d15Sespie // Iostreams base classes -*- C++ -*- 203a78d15Sespie 303a78d15Sespie // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 403a78d15Sespie // Free Software Foundation, Inc. 503a78d15Sespie // 603a78d15Sespie // This file is part of the GNU ISO C++ Library. This library is free 703a78d15Sespie // software; you can redistribute it and/or modify it under the 803a78d15Sespie // terms of the GNU General Public License as published by the 903a78d15Sespie // Free Software Foundation; either version 2, or (at your option) 1003a78d15Sespie // any later version. 1103a78d15Sespie 1203a78d15Sespie // This library is distributed in the hope that it will be useful, 1303a78d15Sespie // but WITHOUT ANY WARRANTY; without even the implied warranty of 1403a78d15Sespie // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1503a78d15Sespie // GNU General Public License for more details. 1603a78d15Sespie 1703a78d15Sespie // You should have received a copy of the GNU General Public License along 1803a78d15Sespie // with this library; see the file COPYING. If not, write to the Free 1903a78d15Sespie // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 2003a78d15Sespie // USA. 2103a78d15Sespie 2203a78d15Sespie // As a special exception, you may use this file as part of a free software 2303a78d15Sespie // library without restriction. Specifically, if other files instantiate 2403a78d15Sespie // templates or use macros or inline functions from this file, or you compile 2503a78d15Sespie // this file and link it with other files to produce an executable, this 2603a78d15Sespie // file does not by itself cause the resulting executable to be covered by 2703a78d15Sespie // the GNU General Public License. This exception does not however 2803a78d15Sespie // invalidate any other reasons why the executable file might be covered by 2903a78d15Sespie // the GNU General Public License. 3003a78d15Sespie 3103a78d15Sespie // 3203a78d15Sespie // ISO C++ 14882: 27.4 Iostreams base classes 3303a78d15Sespie // 3403a78d15Sespie 3503a78d15Sespie #include <ios> 3603a78d15Sespie #include <ostream> 3703a78d15Sespie #include <istream> 3803a78d15Sespie #include <fstream> 3903a78d15Sespie #include <bits/atomicity.h> 4003a78d15Sespie #include <ext/stdio_filebuf.h> 4103a78d15Sespie #ifdef _GLIBCPP_HAVE_UNISTD_H 4203a78d15Sespie #include <unistd.h> 4303a78d15Sespie #endif 4403a78d15Sespie 4503a78d15Sespie namespace __gnu_cxx 4603a78d15Sespie { 4703a78d15Sespie // Extern declarations for global objects in src/globals.cc. 4803a78d15Sespie extern stdio_filebuf<char> buf_cout; 4903a78d15Sespie extern stdio_filebuf<char> buf_cin; 5003a78d15Sespie extern stdio_filebuf<char> buf_cerr; 5103a78d15Sespie 52*c2fb3212Sespie #if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T) 5303a78d15Sespie extern stdio_filebuf<wchar_t> buf_wcout; 5403a78d15Sespie extern stdio_filebuf<wchar_t> buf_wcin; 5503a78d15Sespie extern stdio_filebuf<wchar_t> buf_wcerr; 5603a78d15Sespie #endif 5703a78d15Sespie } // namespace __gnu_cxx 5803a78d15Sespie 5903a78d15Sespie namespace std 6003a78d15Sespie { 6103a78d15Sespie using namespace __gnu_cxx; 6203a78d15Sespie 6303a78d15Sespie extern istream cin; 6403a78d15Sespie extern ostream cout; 6503a78d15Sespie extern ostream cerr; 6603a78d15Sespie extern ostream clog; 6703a78d15Sespie 68*c2fb3212Sespie #if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T) 6903a78d15Sespie extern wistream wcin; 7003a78d15Sespie extern wostream wcout; 7103a78d15Sespie extern wostream wcerr; 7203a78d15Sespie extern wostream wclog; 7303a78d15Sespie #endif 7403a78d15Sespie 7503a78d15Sespie // Definitions for static const data members of __ios_flags. 7603a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_boolalpha; 7703a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_dec; 7803a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_fixed; 7903a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_hex; 8003a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_internal; 8103a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_left; 8203a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_oct; 8303a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_right; 8403a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_scientific; 8503a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_showbase; 8603a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_showpoint; 8703a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_showpos; 8803a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_skipws; 8903a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_unitbuf; 9003a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_uppercase; 9103a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_adjustfield; 9203a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_basefield; 9303a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_floatfield; 9403a78d15Sespie 9503a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_badbit; 9603a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_eofbit; 9703a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_failbit; 9803a78d15Sespie 9903a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_app; 10003a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_ate; 10103a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_bin; 10203a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_in; 10303a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_out; 10403a78d15Sespie const __ios_flags::__int_type __ios_flags::_S_trunc; 10503a78d15Sespie 10603a78d15Sespie // Definitions for static const members of ios_base. 10703a78d15Sespie const ios_base::fmtflags ios_base::boolalpha; 10803a78d15Sespie const ios_base::fmtflags ios_base::dec; 10903a78d15Sespie const ios_base::fmtflags ios_base::fixed; 11003a78d15Sespie const ios_base::fmtflags ios_base::hex; 11103a78d15Sespie const ios_base::fmtflags ios_base::internal; 11203a78d15Sespie const ios_base::fmtflags ios_base::left; 11303a78d15Sespie const ios_base::fmtflags ios_base::oct; 11403a78d15Sespie const ios_base::fmtflags ios_base::right; 11503a78d15Sespie const ios_base::fmtflags ios_base::scientific; 11603a78d15Sespie const ios_base::fmtflags ios_base::showbase; 11703a78d15Sespie const ios_base::fmtflags ios_base::showpoint; 11803a78d15Sespie const ios_base::fmtflags ios_base::showpos; 11903a78d15Sespie const ios_base::fmtflags ios_base::skipws; 12003a78d15Sespie const ios_base::fmtflags ios_base::unitbuf; 12103a78d15Sespie const ios_base::fmtflags ios_base::uppercase; 12203a78d15Sespie const ios_base::fmtflags ios_base::adjustfield; 12303a78d15Sespie const ios_base::fmtflags ios_base::basefield; 12403a78d15Sespie const ios_base::fmtflags ios_base::floatfield; 12503a78d15Sespie 12603a78d15Sespie const ios_base::iostate ios_base::badbit; 12703a78d15Sespie const ios_base::iostate ios_base::eofbit; 12803a78d15Sespie const ios_base::iostate ios_base::failbit; 12903a78d15Sespie const ios_base::iostate ios_base::goodbit; 13003a78d15Sespie 13103a78d15Sespie const ios_base::openmode ios_base::app; 13203a78d15Sespie const ios_base::openmode ios_base::ate; 13303a78d15Sespie const ios_base::openmode ios_base::binary; 13403a78d15Sespie const ios_base::openmode ios_base::in; 13503a78d15Sespie const ios_base::openmode ios_base::out; 13603a78d15Sespie const ios_base::openmode ios_base::trunc; 13703a78d15Sespie 13803a78d15Sespie const ios_base::seekdir ios_base::beg; 13903a78d15Sespie const ios_base::seekdir ios_base::cur; 14003a78d15Sespie const ios_base::seekdir ios_base::end; 14103a78d15Sespie 14203a78d15Sespie const int ios_base::_S_local_word_size; 14303a78d15Sespie int ios_base::Init::_S_ios_base_init = 0; 14403a78d15Sespie bool ios_base::Init::_S_synced_with_stdio = true; 14503a78d15Sespie failure(const string & __str)14603a78d15Sespie ios_base::failure::failure(const string& __str) throw() 14703a78d15Sespie { 14803a78d15Sespie strncpy(_M_name, __str.c_str(), _M_bufsize); 14903a78d15Sespie _M_name[_M_bufsize - 1] = '\0'; 15003a78d15Sespie } 15103a78d15Sespie ~failure()15203a78d15Sespie ios_base::failure::~failure() throw() 15303a78d15Sespie { } 15403a78d15Sespie 15503a78d15Sespie const char* what() const15603a78d15Sespie ios_base::failure::what() const throw() 15703a78d15Sespie { return _M_name; } 15803a78d15Sespie 15903a78d15Sespie void _S_ios_create(bool __sync)16003a78d15Sespie ios_base::Init::_S_ios_create(bool __sync) 16103a78d15Sespie { 16203a78d15Sespie size_t __out_size = __sync ? 0 : static_cast<size_t>(BUFSIZ); 16303a78d15Sespie #ifdef _GLIBCPP_HAVE_ISATTY 16403a78d15Sespie size_t __in_size = 16503a78d15Sespie (__sync || isatty (0)) ? 1 : static_cast<size_t>(BUFSIZ); 16603a78d15Sespie #else 16703a78d15Sespie size_t __in_size = 1; 16803a78d15Sespie #endif 16903a78d15Sespie 17003a78d15Sespie // NB: The file globals.cc creates the four standard files 17103a78d15Sespie // with NULL buffers. At this point, we swap out the dummy NULL 17203a78d15Sespie // [io]stream objects and buffers with the real deal. 17303a78d15Sespie new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out, __out_size); 17403a78d15Sespie new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in, __in_size); 17503a78d15Sespie new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out, __out_size); 17603a78d15Sespie 17703a78d15Sespie new (&cout) ostream(&buf_cout); 17803a78d15Sespie new (&cin) istream(&buf_cin); 17903a78d15Sespie new (&cerr) ostream(&buf_cerr); 18003a78d15Sespie new (&clog) ostream(&buf_cerr); 18103a78d15Sespie cout.init(&buf_cout); 18203a78d15Sespie cin.init(&buf_cin); 18303a78d15Sespie cerr.init(&buf_cerr); 18403a78d15Sespie clog.init(&buf_cerr); 18503a78d15Sespie cin.tie(&cout); 18603a78d15Sespie cerr.flags(ios_base::unitbuf); 18703a78d15Sespie 188*c2fb3212Sespie #if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T) 18903a78d15Sespie new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size); 19003a78d15Sespie new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in, __in_size); 19103a78d15Sespie new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size); 19203a78d15Sespie new (&wcout) wostream(&buf_wcout); 19303a78d15Sespie new (&wcin) wistream(&buf_wcin); 19403a78d15Sespie new (&wcerr) wostream(&buf_wcerr); 19503a78d15Sespie new (&wclog) wostream(&buf_wcerr); 19603a78d15Sespie wcout.init(&buf_wcout); 19703a78d15Sespie wcin.init(&buf_wcin); 19803a78d15Sespie wcerr.init(&buf_wcerr); 19903a78d15Sespie wclog.init(&buf_wcerr); 20003a78d15Sespie wcin.tie(&wcout); 20103a78d15Sespie wcerr.flags(ios_base::unitbuf); 20203a78d15Sespie #endif 20303a78d15Sespie } 20403a78d15Sespie 20503a78d15Sespie void _S_ios_destroy()20603a78d15Sespie ios_base::Init::_S_ios_destroy() 20703a78d15Sespie { 20803a78d15Sespie // Explicitly call dtors to free any memory that is dynamically 20903a78d15Sespie // allocated by filebuf ctor or member functions, but don't 21003a78d15Sespie // deallocate all memory by calling operator delete. 21103a78d15Sespie buf_cout.~stdio_filebuf(); 21203a78d15Sespie buf_cin.~stdio_filebuf(); 21303a78d15Sespie buf_cerr.~stdio_filebuf(); 21403a78d15Sespie 215*c2fb3212Sespie #if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T) 21603a78d15Sespie buf_wcout.~stdio_filebuf(); 21703a78d15Sespie buf_wcin.~stdio_filebuf(); 21803a78d15Sespie buf_wcerr.~stdio_filebuf(); 21903a78d15Sespie #endif 22003a78d15Sespie } 22103a78d15Sespie Init()22203a78d15Sespie ios_base::Init::Init() 22303a78d15Sespie { 22403a78d15Sespie if (_S_ios_base_init == 0) 22503a78d15Sespie { 22603a78d15Sespie // Standard streams default to synced with "C" operations. 22703a78d15Sespie ios_base::Init::_S_synced_with_stdio = true; 22803a78d15Sespie _S_ios_create(ios_base::Init::_S_synced_with_stdio); 22903a78d15Sespie } 23003a78d15Sespie ++_S_ios_base_init; 23103a78d15Sespie } 23203a78d15Sespie ~Init()23303a78d15Sespie ios_base::Init::~Init() 23403a78d15Sespie { 23503a78d15Sespie if (--_S_ios_base_init == 0) 23603a78d15Sespie _S_ios_destroy(); 23703a78d15Sespie } 23803a78d15Sespie 23903a78d15Sespie // 27.4.2.5 ios_base storage functions 24003a78d15Sespie int xalloc()24103a78d15Sespie ios_base::xalloc() throw() 24203a78d15Sespie { 24303a78d15Sespie // Implementation note: Initialize top to zero to ensure that 24403a78d15Sespie // initialization occurs before main() is started. 24503a78d15Sespie static _Atomic_word _S_top = 0; 24603a78d15Sespie return __exchange_and_add(&_S_top, 1) + 4; 24703a78d15Sespie } 24803a78d15Sespie 24903a78d15Sespie // 27.4.2.5 iword/pword storage 25003a78d15Sespie ios_base::_Words& _M_grow_words(int ix)25103a78d15Sespie ios_base::_M_grow_words(int ix) 25203a78d15Sespie { 25303a78d15Sespie // Precondition: _M_word_size <= ix 25403a78d15Sespie int newsize = _S_local_word_size; 25503a78d15Sespie _Words* words = _M_local_word; 25603a78d15Sespie if (ix > _S_local_word_size - 1) 25703a78d15Sespie { 25803a78d15Sespie if (ix < numeric_limits<int>::max()) 25903a78d15Sespie { 26003a78d15Sespie newsize = ix + 1; 26103a78d15Sespie try 26203a78d15Sespie { words = new _Words[newsize]; } 26303a78d15Sespie catch (...) 26403a78d15Sespie { 26503a78d15Sespie _M_streambuf_state |= badbit; 26603a78d15Sespie if (_M_streambuf_state & _M_exception) 26703a78d15Sespie __throw_ios_failure("ios_base::_M_grow_words failure"); 26803a78d15Sespie return _M_word_zero; 26903a78d15Sespie } 27003a78d15Sespie for (int i = 0; i < _M_word_size; i++) 27103a78d15Sespie words[i] = _M_word[i]; 27203a78d15Sespie if (_M_word && _M_word != _M_local_word) 27303a78d15Sespie { 27403a78d15Sespie delete [] _M_word; 27503a78d15Sespie _M_word = 0; 27603a78d15Sespie } 27703a78d15Sespie } 27803a78d15Sespie else 27903a78d15Sespie { 28003a78d15Sespie _M_streambuf_state |= badbit; 28103a78d15Sespie if (_M_streambuf_state & _M_exception) 28203a78d15Sespie __throw_ios_failure("ios_base::_M_grow_words failure"); 28303a78d15Sespie return _M_word_zero; 28403a78d15Sespie } 28503a78d15Sespie } 28603a78d15Sespie _M_word = words; 28703a78d15Sespie _M_word_size = newsize; 28803a78d15Sespie return _M_word[ix]; 28903a78d15Sespie } 29003a78d15Sespie 29103a78d15Sespie // Called only by basic_ios<>::init. 29203a78d15Sespie void _M_init()29303a78d15Sespie ios_base::_M_init() 29403a78d15Sespie { 29503a78d15Sespie // NB: May be called more than once 29603a78d15Sespie _M_precision = 6; 29703a78d15Sespie _M_width = 0; 29803a78d15Sespie _M_flags = skipws | dec; 29903a78d15Sespie _M_ios_locale = locale(); 30003a78d15Sespie } 30103a78d15Sespie 30203a78d15Sespie // 27.4.2.3 ios_base locale functions 30303a78d15Sespie locale imbue(const locale & __loc)30403a78d15Sespie ios_base::imbue(const locale& __loc) 30503a78d15Sespie { 30603a78d15Sespie locale __old = _M_ios_locale; 30703a78d15Sespie _M_ios_locale = __loc; 30803a78d15Sespie _M_call_callbacks(imbue_event); 30903a78d15Sespie return __old; 31003a78d15Sespie } 31103a78d15Sespie ios_base()31203a78d15Sespie ios_base::ios_base() : _M_callbacks(0), _M_word_size(_S_local_word_size), 31303a78d15Sespie _M_word(_M_local_word) 31403a78d15Sespie { 31503a78d15Sespie // Do nothing: basic_ios::init() does it. 31603a78d15Sespie // NB: _M_callbacks and _M_word must be zero for non-initialized 31703a78d15Sespie // ios_base to go through ~ios_base gracefully. 31803a78d15Sespie } 31903a78d15Sespie 32003a78d15Sespie // 27.4.2.7 ios_base constructors/destructors ~ios_base()32103a78d15Sespie ios_base::~ios_base() 32203a78d15Sespie { 32303a78d15Sespie _M_call_callbacks(erase_event); 32403a78d15Sespie _M_dispose_callbacks(); 32503a78d15Sespie if (_M_word != _M_local_word) 32603a78d15Sespie { 32703a78d15Sespie delete [] _M_word; 32803a78d15Sespie _M_word = 0; 32903a78d15Sespie } 33003a78d15Sespie } 33103a78d15Sespie 33203a78d15Sespie void register_callback(event_callback __fn,int __index)33303a78d15Sespie ios_base::register_callback(event_callback __fn, int __index) 33403a78d15Sespie { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); } 33503a78d15Sespie 33603a78d15Sespie void _M_call_callbacks(event __e)33703a78d15Sespie ios_base::_M_call_callbacks(event __e) throw() 33803a78d15Sespie { 33903a78d15Sespie _Callback_list* __p = _M_callbacks; 34003a78d15Sespie while (__p) 34103a78d15Sespie { 34203a78d15Sespie try 34303a78d15Sespie { (*__p->_M_fn) (__e, *this, __p->_M_index); } 34403a78d15Sespie catch (...) 34503a78d15Sespie { } 34603a78d15Sespie __p = __p->_M_next; 34703a78d15Sespie } 34803a78d15Sespie } 34903a78d15Sespie 35003a78d15Sespie void _M_dispose_callbacks(void)35103a78d15Sespie ios_base::_M_dispose_callbacks(void) 35203a78d15Sespie { 35303a78d15Sespie _Callback_list* __p = _M_callbacks; 35403a78d15Sespie while (__p && __p->_M_remove_reference() == 0) 35503a78d15Sespie { 35603a78d15Sespie _Callback_list* __next = __p->_M_next; 35703a78d15Sespie delete __p; 35803a78d15Sespie __p = __next; 35903a78d15Sespie } 36003a78d15Sespie _M_callbacks = 0; 36103a78d15Sespie } 36203a78d15Sespie 36303a78d15Sespie bool sync_with_stdio(bool __sync)36403a78d15Sespie ios_base::sync_with_stdio(bool __sync) 36503a78d15Sespie { 36603a78d15Sespie #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 36703a78d15Sespie // 49. Underspecification of ios_base::sync_with_stdio 36803a78d15Sespie bool __ret = ios_base::Init::_S_synced_with_stdio; 36903a78d15Sespie #endif 37003a78d15Sespie 37103a78d15Sespie // Turn off sync with C FILE* for cin, cout, cerr, clog iff 37203a78d15Sespie // currently synchronized. 37303a78d15Sespie if (!__sync && __ret) 37403a78d15Sespie { 37503a78d15Sespie ios_base::Init::_S_synced_with_stdio = false; 37603a78d15Sespie ios_base::Init::_S_ios_destroy(); 37703a78d15Sespie ios_base::Init::_S_ios_create(ios_base::Init::_S_synced_with_stdio); 37803a78d15Sespie } 37903a78d15Sespie return __ret; 38003a78d15Sespie } 38103a78d15Sespie } // namespace std 382