xref: /freebsd-12.1/contrib/libstdc++/src/ios.cc (revision f8a1b7d9)
100db7afdSDavid E. O'Brien // Iostreams base classes -*- C++ -*-
200db7afdSDavid E. O'Brien 
3*f8a1b7d9SAlexander Kabaev // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
400db7afdSDavid E. O'Brien // Free Software Foundation, Inc.
500db7afdSDavid E. O'Brien //
600db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library.  This library is free
700db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
800db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
900db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
1000db7afdSDavid E. O'Brien // any later version.
1100db7afdSDavid E. O'Brien 
1200db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
1300db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
1400db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1500db7afdSDavid E. O'Brien // GNU General Public License for more details.
1600db7afdSDavid E. O'Brien 
1700db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
1800db7afdSDavid E. O'Brien // with this library; see the file COPYING.  If not, write to the Free
19*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2000db7afdSDavid E. O'Brien // USA.
2100db7afdSDavid E. O'Brien 
2200db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
2300db7afdSDavid E. O'Brien // library without restriction.  Specifically, if other files instantiate
2400db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
2500db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
2600db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
2700db7afdSDavid E. O'Brien // the GNU General Public License.  This exception does not however
2800db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
2900db7afdSDavid E. O'Brien // the GNU General Public License.
3000db7afdSDavid E. O'Brien 
3100db7afdSDavid E. O'Brien //
3200db7afdSDavid E. O'Brien // ISO C++ 14882: 27.4  Iostreams base classes
3300db7afdSDavid E. O'Brien //
3400db7afdSDavid E. O'Brien 
3500db7afdSDavid E. O'Brien #include <ios>
36ffeaf689SAlexander Kabaev #include <limits>
378f1134fbSDavid E. O'Brien 
38*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(std)
3900db7afdSDavid E. O'Brien 
4000db7afdSDavid E. O'Brien   // Definitions for static const members of ios_base.
4100db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::boolalpha;
4200db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::dec;
4300db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::fixed;
4400db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::hex;
4500db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::internal;
4600db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::left;
4700db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::oct;
4800db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::right;
4900db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::scientific;
5000db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::showbase;
5100db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::showpoint;
5200db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::showpos;
5300db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::skipws;
5400db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::unitbuf;
5500db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::uppercase;
5600db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::adjustfield;
5700db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::basefield;
5800db7afdSDavid E. O'Brien   const ios_base::fmtflags ios_base::floatfield;
5900db7afdSDavid E. O'Brien 
6000db7afdSDavid E. O'Brien   const ios_base::iostate ios_base::badbit;
6100db7afdSDavid E. O'Brien   const ios_base::iostate ios_base::eofbit;
6200db7afdSDavid E. O'Brien   const ios_base::iostate ios_base::failbit;
6300db7afdSDavid E. O'Brien   const ios_base::iostate ios_base::goodbit;
6400db7afdSDavid E. O'Brien 
6500db7afdSDavid E. O'Brien   const ios_base::openmode ios_base::app;
6600db7afdSDavid E. O'Brien   const ios_base::openmode ios_base::ate;
6700db7afdSDavid E. O'Brien   const ios_base::openmode ios_base::binary;
6800db7afdSDavid E. O'Brien   const ios_base::openmode ios_base::in;
6900db7afdSDavid E. O'Brien   const ios_base::openmode ios_base::out;
7000db7afdSDavid E. O'Brien   const ios_base::openmode ios_base::trunc;
7100db7afdSDavid E. O'Brien 
7200db7afdSDavid E. O'Brien   const ios_base::seekdir ios_base::beg;
7300db7afdSDavid E. O'Brien   const ios_base::seekdir ios_base::cur;
7400db7afdSDavid E. O'Brien   const ios_base::seekdir ios_base::end;
7500db7afdSDavid E. O'Brien 
76ffeaf689SAlexander Kabaev   _Atomic_word ios_base::Init::_S_refcount;
77ffeaf689SAlexander Kabaev 
7800db7afdSDavid E. O'Brien   bool ios_base::Init::_S_synced_with_stdio = true;
7900db7afdSDavid E. O'Brien 
ios_base()80ffeaf689SAlexander Kabaev   ios_base::ios_base()
81ffeaf689SAlexander Kabaev   : _M_precision(), _M_width(), _M_flags(), _M_exception(),
82ffeaf689SAlexander Kabaev   _M_streambuf_state(), _M_callbacks(0), _M_word_zero(),
83ffeaf689SAlexander Kabaev   _M_word_size(_S_local_word_size), _M_word(_M_local_word), _M_ios_locale()
8400db7afdSDavid E. O'Brien   {
8500db7afdSDavid E. O'Brien     // Do nothing: basic_ios::init() does it.
8600db7afdSDavid E. O'Brien     // NB: _M_callbacks and _M_word must be zero for non-initialized
8700db7afdSDavid E. O'Brien     // ios_base to go through ~ios_base gracefully.
8800db7afdSDavid E. O'Brien   }
8900db7afdSDavid E. O'Brien 
9000db7afdSDavid E. O'Brien   // 27.4.2.7  ios_base constructors/destructors
~ios_base()9100db7afdSDavid E. O'Brien   ios_base::~ios_base()
9200db7afdSDavid E. O'Brien   {
9300db7afdSDavid E. O'Brien     _M_call_callbacks(erase_event);
9400db7afdSDavid E. O'Brien     _M_dispose_callbacks();
951b86b14eSAlexander Kabaev     if (_M_word != _M_local_word)
9600db7afdSDavid E. O'Brien       {
9700db7afdSDavid E. O'Brien 	delete [] _M_word;
9800db7afdSDavid E. O'Brien 	_M_word = 0;
9900db7afdSDavid E. O'Brien       }
10000db7afdSDavid E. O'Brien   }
10100db7afdSDavid E. O'Brien 
102ffeaf689SAlexander Kabaev   // 27.4.2.5  ios_base storage functions
103ffeaf689SAlexander Kabaev   int
xalloc()104ffeaf689SAlexander Kabaev   ios_base::xalloc() throw()
105ffeaf689SAlexander Kabaev   {
106ffeaf689SAlexander Kabaev     // Implementation note: Initialize top to zero to ensure that
107ffeaf689SAlexander Kabaev     // initialization occurs before main() is started.
108ffeaf689SAlexander Kabaev     static _Atomic_word _S_top = 0;
109*f8a1b7d9SAlexander Kabaev     return __gnu_cxx::__exchange_and_add_dispatch(&_S_top, 1) + 4;
110ffeaf689SAlexander Kabaev   }
111ffeaf689SAlexander Kabaev 
11200db7afdSDavid E. O'Brien   void
register_callback(event_callback __fn,int __index)11300db7afdSDavid E. O'Brien   ios_base::register_callback(event_callback __fn, int __index)
11400db7afdSDavid E. O'Brien   { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); }
11500db7afdSDavid E. O'Brien 
116ffeaf689SAlexander Kabaev   // 27.4.2.5  iword/pword storage
117ffeaf689SAlexander Kabaev   ios_base::_Words&
_M_grow_words(int __ix,bool __iword)118*f8a1b7d9SAlexander Kabaev   ios_base::_M_grow_words(int __ix, bool __iword)
119ffeaf689SAlexander Kabaev   {
120*f8a1b7d9SAlexander Kabaev     // Precondition: _M_word_size <= __ix
121*f8a1b7d9SAlexander Kabaev     int __newsize = _S_local_word_size;
122*f8a1b7d9SAlexander Kabaev     _Words* __words = _M_local_word;
123*f8a1b7d9SAlexander Kabaev     if (__ix > _S_local_word_size - 1)
124ffeaf689SAlexander Kabaev       {
125*f8a1b7d9SAlexander Kabaev 	if (__ix < numeric_limits<int>::max())
126ffeaf689SAlexander Kabaev 	  {
127*f8a1b7d9SAlexander Kabaev 	    __newsize = __ix + 1;
128ffeaf689SAlexander Kabaev 	    try
129*f8a1b7d9SAlexander Kabaev 	      { __words = new _Words[__newsize]; }
130ffeaf689SAlexander Kabaev 	    catch (...)
131ffeaf689SAlexander Kabaev 	      {
132ffeaf689SAlexander Kabaev 		_M_streambuf_state |= badbit;
133ffeaf689SAlexander Kabaev 		if (_M_streambuf_state & _M_exception)
134ffeaf689SAlexander Kabaev 		  __throw_ios_failure(__N("ios_base::_M_grow_words "
135ffeaf689SAlexander Kabaev 				      "allocation failed"));
136*f8a1b7d9SAlexander Kabaev 		if (__iword)
137ffeaf689SAlexander Kabaev 		  _M_word_zero._M_iword = 0;
138ffeaf689SAlexander Kabaev 		else
139ffeaf689SAlexander Kabaev 		  _M_word_zero._M_pword = 0;
140ffeaf689SAlexander Kabaev 		return _M_word_zero;
141ffeaf689SAlexander Kabaev 	      }
142*f8a1b7d9SAlexander Kabaev 	    for (int __i = 0; __i < _M_word_size; __i++)
143*f8a1b7d9SAlexander Kabaev 	      __words[__i] = _M_word[__i];
144ffeaf689SAlexander Kabaev 	    if (_M_word && _M_word != _M_local_word)
145ffeaf689SAlexander Kabaev 	      {
146ffeaf689SAlexander Kabaev 		delete [] _M_word;
147ffeaf689SAlexander Kabaev 		_M_word = 0;
148ffeaf689SAlexander Kabaev 	      }
149ffeaf689SAlexander Kabaev 	  }
150ffeaf689SAlexander Kabaev 	else
151ffeaf689SAlexander Kabaev 	  {
152ffeaf689SAlexander Kabaev 	    _M_streambuf_state |= badbit;
153ffeaf689SAlexander Kabaev 	    if (_M_streambuf_state & _M_exception)
154ffeaf689SAlexander Kabaev 	      __throw_ios_failure(__N("ios_base::_M_grow_words is not valid"));
155*f8a1b7d9SAlexander Kabaev 	    if (__iword)
156ffeaf689SAlexander Kabaev 	      _M_word_zero._M_iword = 0;
157ffeaf689SAlexander Kabaev 	    else
158ffeaf689SAlexander Kabaev 	      _M_word_zero._M_pword = 0;
159ffeaf689SAlexander Kabaev 	    return _M_word_zero;
160ffeaf689SAlexander Kabaev 	  }
161ffeaf689SAlexander Kabaev       }
162*f8a1b7d9SAlexander Kabaev     _M_word = __words;
163*f8a1b7d9SAlexander Kabaev     _M_word_size = __newsize;
164*f8a1b7d9SAlexander Kabaev     return _M_word[__ix];
165ffeaf689SAlexander Kabaev   }
166ffeaf689SAlexander Kabaev 
16700db7afdSDavid E. O'Brien   void
_M_call_callbacks(event __e)16800db7afdSDavid E. O'Brien   ios_base::_M_call_callbacks(event __e) throw()
16900db7afdSDavid E. O'Brien   {
17000db7afdSDavid E. O'Brien     _Callback_list* __p = _M_callbacks;
17100db7afdSDavid E. O'Brien     while (__p)
17200db7afdSDavid E. O'Brien       {
17300db7afdSDavid E. O'Brien 	try
17400db7afdSDavid E. O'Brien 	  { (*__p->_M_fn) (__e, *this, __p->_M_index); }
17500db7afdSDavid E. O'Brien 	catch (...)
17600db7afdSDavid E. O'Brien 	  { }
17700db7afdSDavid E. O'Brien 	__p = __p->_M_next;
17800db7afdSDavid E. O'Brien       }
17900db7afdSDavid E. O'Brien   }
18000db7afdSDavid E. O'Brien 
18100db7afdSDavid E. O'Brien   void
_M_dispose_callbacks(void)18200db7afdSDavid E. O'Brien   ios_base::_M_dispose_callbacks(void)
18300db7afdSDavid E. O'Brien   {
18400db7afdSDavid E. O'Brien     _Callback_list* __p = _M_callbacks;
18500db7afdSDavid E. O'Brien     while (__p && __p->_M_remove_reference() == 0)
18600db7afdSDavid E. O'Brien       {
18700db7afdSDavid E. O'Brien 	_Callback_list* __next = __p->_M_next;
18800db7afdSDavid E. O'Brien 	delete __p;
18900db7afdSDavid E. O'Brien 	__p = __next;
19000db7afdSDavid E. O'Brien       }
19100db7afdSDavid E. O'Brien     _M_callbacks = 0;
19200db7afdSDavid E. O'Brien   }
193*f8a1b7d9SAlexander Kabaev 
194*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
195