This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[v3] io fixes part 1
- To: gcc-patches at gcc dot gnu dot org, libstdc++ at gcc dot gnu dot org
- Subject: [v3] io fixes part 1
- From: Benjamin Kosnik <bkoz at redhat dot com>
- Date: Fri, 5 Jan 2001 18:41:38 -0800
Fixes for
http://gcc.gnu.org/ml/libstdc++/2000-11/msg00295.html
http://gcc.gnu.org/ml/libstdc++/2000-12/msg00313.html
Based on work from Loren.
Unresolved are sync_with_stdio(false), and sync_with_stdio(true).
Fixes 27_io/filebuf_members.cc
tested x86/linux
2001-01-05 Benjamin Kosnik <bkoz@fillmore.constant.com>
* src/localename.cc (locale::_Impl::_Impl(const _Impl& __imp,
const string& __name, category __cat, size_t __refs): Set
_M_has_name with _M_name.
* include/bits/localefwd.h (locale::operator!=): Protect member
function call with this->.
* src/locale.cc (locale::operator==): Make fast checks first.
* include/bits/basic_ios.tcc (basic_ios::init): Don't use
temporary value for locale.
* include/bits/ios_base.h (_M_synced_with_stdio): Add data member
to ios_base::Init.
* src/ios.cc (ios_base::Init::Init): Initialize here.
(ios_base::sync_with_stdio): Set here.
2001-01-04 Loren J. Rittle <ljrittle@acm.org>
* config/c_io_stdio.cc (__basic_file<_CharT>::sys_open()): On
systems that support it, call dup() before fdopen().
Index: config/c_io_stdio.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/config/c_io_stdio.cc,v
retrieving revision 1.2
diff -c -p -r1.2 c_io_stdio.cc
*** c_io_stdio.cc 2000/11/22 06:37:34 1.2
--- c_io_stdio.cc 2001/01/06 02:38:10
***************
*** 1,6 ****
// Wrapper of C-language FILE struct -*- C++ -*-
! // Copyright (C) 2000 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
--- 1,6 ----
// Wrapper of C-language FILE struct -*- C++ -*-
! // Copyright (C) 2000, 2001 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
***************
*** 32,37 ****
--- 32,38 ----
//
#include <bits/basic_file.h>
+ #include <unistd.h>
namespace std {
*************** namespace std {
*** 94,107 ****
_M_open_mode(__mode, __p_mode, __rw_mode, __c_mode);
! if (!this->is_open())
{
! if ((_M_cfile = fdopen(__fd, __c_mode)))
{
! _M_fileno = __fd;
__ret = this;
}
}
return __ret;
}
--- 95,111 ----
_M_open_mode(__mode, __p_mode, __rw_mode, __c_mode);
! int __dupfd = dup(__fd);
!
! if (__dupfd != -1 && !this->is_open())
{
! if ((_M_cfile = fdopen(__dupfd, __c_mode)))
{
! _M_fileno = __dupfd;
__ret = this;
}
}
+
return __ret;
}
*************** namespace std {
*** 225,231 ****
template<typename _CharT>
streamoff
__basic_file<_CharT>::sys_seek(streamoff __pos, ios_base::seekdir __way)
! { fseek(_M_cfile, __pos, __way); return ftell(_M_cfile); }
// NB: Unused.
template<typename _CharT>
--- 229,238 ----
template<typename _CharT>
streamoff
__basic_file<_CharT>::sys_seek(streamoff __pos, ios_base::seekdir __way)
! {
! fseek(_M_cfile, __pos, __way);
! return ftell(_M_cfile);
! }
// NB: Unused.
template<typename _CharT>
Index: include/bits/basic_ios.tcc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/basic_ios.tcc,v
retrieving revision 1.1
diff -c -p -r1.1 basic_ios.tcc
*** basic_ios.tcc 2000/10/05 11:27:01 1.1
--- basic_ios.tcc 2001/01/06 02:38:12
*************** namespace std {
*** 119,135 ****
{
// NB: This may be called more than once on the same object.
ios_base::_M_init();
! locale __loc = this->getloc();
! _M_ios_fctype = &use_facet<__ctype_type>(__loc);
// Should be filled in by ostream and istream, respectively.
! _M_fnumput = &use_facet<__numput_type>(__loc);
! _M_fnumget = &use_facet<__numget_type>(__loc);
_M_tie = 0;
_M_fill = this->widen(' ');
_M_exception = goodbit;
_M_streambuf = __sb;
! iostate __state = __sb ? goodbit : badbit;
! _M_streambuf_state = __state;
}
} // namespace std
--- 119,133 ----
{
// NB: This may be called more than once on the same object.
ios_base::_M_init();
! _M_ios_fctype = &use_facet<__ctype_type>(_M_ios_locale);
// Should be filled in by ostream and istream, respectively.
! _M_fnumput = &use_facet<__numput_type>(_M_ios_locale);
! _M_fnumget = &use_facet<__numget_type>(_M_ios_locale);
_M_tie = 0;
_M_fill = this->widen(' ');
_M_exception = goodbit;
_M_streambuf = __sb;
! _M_streambuf_state = __sb ? goodbit : badbit;
}
} // namespace std
Index: include/bits/ios_base.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.4
diff -c -p -r1.4 ios_base.h
*** ios_base.h 2000/12/14 07:20:37 1.4
--- ios_base.h 2001/01/06 02:38:13
***************
*** 1,6 ****
// Iostreams base classes -*- C++ -*-
! // Copyright (C) 1997-2000 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
--- 1,6 ----
// Iostreams base classes -*- C++ -*-
! // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
*************** namespace std {
*** 294,299 ****
--- 294,300 ----
~Init();
private:
static int _S_ios_base_init;
+ bool _M_synced_with_stdio;
filebuf* _M_cout;
filebuf* _M_cin;
filebuf* _M_cerr;
Index: include/bits/localefwd.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/localefwd.h,v
retrieving revision 1.7
diff -c -p -r1.7 localefwd.h
*** localefwd.h 2000/12/22 11:06:17 1.7
--- localefwd.h 2001/01/06 02:38:15
*************** namespace std
*** 270,276 ****
inline bool
operator!=(const locale& __other) const throw ()
! { return !(operator==(__other)); }
template<typename _Char, typename _Traits, typename _Alloc>
bool
--- 270,276 ----
inline bool
operator!=(const locale& __other) const throw ()
! { return !(this->operator==(__other)); }
template<typename _Char, typename _Traits, typename _Alloc>
bool
*************** namespace std
*** 361,370 ****
}
}
! _Impl(const _Impl&, size_t __refs);
! _Impl(const _Impl&, const string&, category, size_t __refs);
! _Impl(size_t __facets, size_t __refs, bool __has_name,
! string __name = "*");
~_Impl() throw();
void
--- 361,369 ----
}
}
! _Impl(const _Impl&, size_t);
! _Impl(const _Impl&, const string&, category, size_t);
! _Impl(size_t, size_t, bool __has_name = false, string __name = "*");
~_Impl() throw();
void
Index: src/ios.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/src/ios.cc,v
retrieving revision 1.8
diff -c -p -r1.8 ios.cc
*** ios.cc 2000/12/20 08:04:41 1.8
--- ios.cc 2001/01/06 02:38:17
***************
*** 1,6 ****
// Iostreams base classes -*- C++ -*-
! // Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
--- 1,6 ----
// Iostreams base classes -*- C++ -*-
! // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
***************
*** 35,42 ****
#include <bits/std_iostream.h>
#include <bits/std_fstream.h>
! namespace std {
!
// Definitions for static const data members of __ios_flags.
const __ios_flags::__int_type __ios_flags::_S_boolalpha;
const __ios_flags::__int_type __ios_flags::_S_dec;
--- 35,42 ----
#include <bits/std_iostream.h>
#include <bits/std_fstream.h>
! namespace std
! {
// Definitions for static const data members of __ios_flags.
const __ios_flags::__int_type __ios_flags::_S_boolalpha;
const __ios_flags::__int_type __ios_flags::_S_dec;
*************** namespace std {
*** 159,164 ****
--- 159,165 ----
__wold = wclog.rdbuf(_M_wcerr);
__wold->~wstreambuf();
#endif
+ _M_synced_with_stdio = true;
}
}
*************** namespace std {
*** 237,245 ****
ios_base::_M_init()
{
// NB: May be called more than once
- _M_flags = skipws | dec;
- _M_width = 0;
_M_precision = 6;
_M_callbacks = 0;
_M_words = 0;
_M_word_limit = 0;
--- 238,246 ----
ios_base::_M_init()
{
// NB: May be called more than once
_M_precision = 6;
+ _M_width = 0;
+ _M_flags = skipws | dec;
_M_callbacks = 0;
_M_words = 0;
_M_word_limit = 0;
*************** namespace std {
*** 313,321 ****
{
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 49. Underspecification of ios_base::sync_with_stdio
! bool __ret = __ioinit._M_cin->_M_file->get_fileno() == 0;
! // Turn off sync with C FILE* for cin, cout, cerr, clog.
if (!__sync && __ret)
{
// Need to dispose of the buffers created at initialization.
--- 314,324 ----
{
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 49. Underspecification of ios_base::sync_with_stdio
! bool __ret = __ioinit._M_synced_with_stdio;
! #endif
! // Turn off sync with C FILE* for cin, cout, cerr, clog iff
! // currently synchronized.
if (!__sync && __ret)
{
// Need to dispose of the buffers created at initialization.
*************** namespace std {
*** 349,358 ****
wcerr.flags(ios_base::unitbuf);
wclog.rdbuf(__ioinit._M_wcerr);
#endif
}
return __ret;
- #endif
}
} // namespace std
--- 352,361 ----
wcerr.flags(ios_base::unitbuf);
wclog.rdbuf(__ioinit._M_wcerr);
#endif
+ __ioinit._M_synced_with_stdio = false;
}
return __ret;
}
} // namespace std
Index: src/locale.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/src/locale.cc,v
retrieving revision 1.24
diff -c -p -r1.24 locale.cc
*** locale.cc 2000/12/22 11:03:33 1.24
--- locale.cc 2001/01/06 02:38:19
*************** namespace std
*** 623,630 ****
bool
locale::operator==(const locale& __rhs) const throw()
{
! return((this->name() != "*" && this->name() == __rhs.name())
! || _M_impl == __rhs._M_impl);
}
const locale&
--- 623,630 ----
bool
locale::operator==(const locale& __rhs) const throw()
{
! return (_M_impl == __rhs._M_impl
! || (this->name() != "*" && this->name() == __rhs.name()));
}
const locale&
Index: src/localename.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/src/localename.cc,v
retrieving revision 1.10
diff -c -p -r1.10 localename.cc
*** localename.cc 2000/12/22 11:03:33 1.10
--- localename.cc 2001/01/06 02:38:20
***************
*** 1,4 ****
! // Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
--- 1,4 ----
! // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
*************** namespace std {
*** 45,56 ****
}
locale::_Impl::
! _Impl(const _Impl& __other, size_t __refs)
: _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
! _M_has_name(__other._M_has_name), _M_name(__other._M_name)
{
try
! { _M_facets = new __vec_facet(*(__other._M_facets)); }
catch(...)
{
delete _M_facets;
--- 45,56 ----
}
locale::_Impl::
! _Impl(const _Impl& __imp, size_t __refs)
: _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
! _M_has_name(__imp._M_has_name), _M_name(__imp._M_name)
{
try
! { _M_facets = new __vec_facet(*(__imp._M_facets)); }
catch(...)
{
delete _M_facets;
*************** namespace std {
*** 58,64 ****
}
try
! { _M_category_names = new __vec_string(*(__other._M_category_names)); }
catch(...)
{
delete _M_category_names;
--- 58,64 ----
}
try
! { _M_category_names = new __vec_string(*(__imp._M_category_names)); }
catch(...)
{
delete _M_category_names;
*************** namespace std {
*** 73,85 ****
// This constructor is used to correctly initialize named locales,
// including the standard "C" locale.
locale::_Impl::
! _Impl(size_t __numfacets, size_t __refs, bool __has_name = false,
! string __name)
: _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
! _M_has_name(__has_name), _M_name(__name)
{
try
! { _M_facets = new __vec_facet(__numfacets, NULL); }
catch(...)
{
delete _M_facets;
--- 73,84 ----
// This constructor is used to correctly initialize named locales,
// including the standard "C" locale.
locale::_Impl::
! _Impl(size_t __num, size_t __refs, bool __has_name, string __str)
: _M_references(__refs - 1), _M_facets(0), _M_category_names(0),
! _M_has_name(__has_name), _M_name(__str)
{
try
! { _M_facets = new __vec_facet(__num, NULL); }
catch(...)
{
delete _M_facets;
*************** namespace std {
*** 97,110 ****
// Construct specific categories, leaving unselected ones alone
locale::_Impl::
! _Impl(const _Impl& __other, const string& __name, category __cat,
! size_t __refs)
! : _M_references(__refs - 1), _M_has_name(__other._M_name != "*")
{
__cat = _S_normalize_category(__cat); // might throw
try
! { _M_facets = new __vec_facet(*(__other._M_facets)); }
catch(...)
{
delete _M_facets;
--- 96,108 ----
// Construct specific categories, leaving unselected ones alone
locale::_Impl::
! _Impl(const _Impl& __imp, const string& __str, category __cat, size_t __refs)
! : _M_references(__refs - 1)
{
__cat = _S_normalize_category(__cat); // might throw
try
! { _M_facets = new __vec_facet(*(__imp._M_facets)); }
catch(...)
{
delete _M_facets;
*************** namespace std {
*** 112,118 ****
}
try
! { _M_category_names = new __vec_string(*(__other._M_category_names)); }
catch(...)
{
delete _M_category_names;
--- 110,116 ----
}
try
! { _M_category_names = new __vec_string(*(__imp._M_category_names)); }
catch(...)
{
delete _M_category_names;
*************** namespace std {
*** 146,152 ****
if (mask & __cat)
_M_replace_category(_S_classic, _S_facet_categories[ix]);
else
! (this->*ctors[ix])(__name.c_str());
}
}
catch(...)
--- 144,150 ----
if (mask & __cat)
_M_replace_category(_S_classic, _S_facet_categories[ix]);
else
! (this->*ctors[ix])(__str.c_str());
}
}
catch(...)
*************** namespace std {
*** 159,201 ****
// XXX May need to be adjusted
if (__cat == all)
! _M_name = __name;
}
void
locale::_Impl::
! _M_replace_categories(const _Impl* __other, category __cat)
{
category __mask = locale::all & -static_cast<unsigned int>(locale::all);
for (unsigned int __ix = 0; (-__mask & __cat) != 0; ++__ix, (__mask <<= 1))
{
if (__mask & __cat)
{
! _M_replace_category(__other, _S_facet_categories[__ix]);
! (*_M_category_names)[__ix] = (*(__other->_M_category_names))[__ix];
}
}
}
void
locale::_Impl::
! _M_replace_category(const _Impl* __other, const locale::id* const* __idpp)
{
for (; *__idpp; ++__idpp)
! _M_replace_facet(__other, *__idpp);
}
void
locale::_Impl::
! _M_replace_facet(const _Impl* __other, const locale::id* __idp)
{
size_t __index = __idp->_M_index;
if (__index == 0
! || __other->_M_facets->size() <= __index
! || (*(__other->_M_facets))[__index] == 0)
throw runtime_error("no locale facet");
! _M_install_facet(__idp, (*(__other->_M_facets))[__index]);
}
void
--- 157,200 ----
// XXX May need to be adjusted
if (__cat == all)
! _M_name = __str;
! _M_has_name = __str != "*";
}
void
locale::_Impl::
! _M_replace_categories(const _Impl* __imp, category __cat)
{
category __mask = locale::all & -static_cast<unsigned int>(locale::all);
for (unsigned int __ix = 0; (-__mask & __cat) != 0; ++__ix, (__mask <<= 1))
{
if (__mask & __cat)
{
! _M_replace_category(__imp, _S_facet_categories[__ix]);
! (*_M_category_names)[__ix] = (*(__imp->_M_category_names))[__ix];
}
}
}
void
locale::_Impl::
! _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp)
{
for (; *__idpp; ++__idpp)
! _M_replace_facet(__imp, *__idpp);
}
void
locale::_Impl::
! _M_replace_facet(const _Impl* __imp, const locale::id* __idp)
{
size_t __index = __idp->_M_index;
if (__index == 0
! || __imp->_M_facets->size() <= __index
! || (*(__imp->_M_facets))[__index] == 0)
throw runtime_error("no locale facet");
! _M_install_facet(__idp, (*(__imp->_M_facets))[__index]);
}
void
*************** namespace std {
*** 220,289 ****
}
void
! locale::_Impl::_M_construct_collate(const char* __name)
{
! _M_facet_init(new collate_byname<char>(__name, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
! _M_facet_init(new collate_byname<wchar_t>(__name, 0));
#endif
}
void
! locale::_Impl::_M_construct_ctype(const char* __name)
{
! _M_facet_init(new ctype_byname<char>(__name, 0));
! _M_facet_init(new codecvt_byname<char, char, mbstate_t>(__name));
#ifdef _GLIBCPP_USE_WCHAR_T
! _M_facet_init(new ctype_byname<wchar_t>(__name, 0));
! _M_facet_init(new codecvt_byname<wchar_t, char, mbstate_t>(__name));
#endif
}
void
! locale::_Impl::_M_construct_monetary(const char* __name)
{
_M_replace_facet(locale::_S_classic, &money_get<char>::id);
_M_replace_facet(locale::_S_classic, &money_put<char>::id);
! _M_facet_init(new moneypunct_byname<char, false>(__name, 0));
! _M_facet_init(new moneypunct_byname<char, true >(__name, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_replace_facet(locale::_S_classic, &money_get<wchar_t>::id);
_M_replace_facet(locale::_S_classic, &money_put<wchar_t>::id);
! _M_facet_init(new moneypunct_byname<wchar_t, false>(__name, 0));
! _M_facet_init(new moneypunct_byname<wchar_t, true >(__name, 0));
#endif
}
void
! locale::_Impl::_M_construct_numeric(const char* __name)
{
_M_replace_facet(locale::_S_classic, &num_get<char>::id);
_M_replace_facet(locale::_S_classic, &num_put<char>::id);
! _M_facet_init(new numpunct_byname<char>(__name, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_replace_facet(locale::_S_classic, &num_get<wchar_t>::id);
_M_replace_facet(locale::_S_classic, &num_put<wchar_t>::id);
! _M_facet_init(new numpunct_byname<wchar_t>(__name, 0));
#endif
}
void
! locale::_Impl::_M_construct_time(const char* __name)
{
! _M_facet_init(new time_get_byname<char>(__name, 0));
! _M_facet_init(new time_put_byname<char>(__name, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
! _M_facet_init(new time_get_byname<wchar_t>(__name, 0));
! _M_facet_init(new time_put_byname<wchar_t>(__name, 0));
#endif
}
void
! locale::_Impl::_M_construct_messages(const char* __name)
{
! _M_facet_init(new messages_byname<char>(__name, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
! _M_facet_init(new messages_byname<wchar_t>(__name, 0));
#endif
}
}
--- 219,288 ----
}
void
! locale::_Impl::_M_construct_collate(const char* __s)
{
! _M_facet_init(new collate_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
! _M_facet_init(new collate_byname<wchar_t>(__s, 0));
#endif
}
void
! locale::_Impl::_M_construct_ctype(const char* __s)
{
! _M_facet_init(new ctype_byname<char>(__s, 0));
! _M_facet_init(new codecvt_byname<char, char, mbstate_t>(__s));
#ifdef _GLIBCPP_USE_WCHAR_T
! _M_facet_init(new ctype_byname<wchar_t>(__s, 0));
! _M_facet_init(new codecvt_byname<wchar_t, char, mbstate_t>(__s));
#endif
}
void
! locale::_Impl::_M_construct_monetary(const char* __s)
{
_M_replace_facet(locale::_S_classic, &money_get<char>::id);
_M_replace_facet(locale::_S_classic, &money_put<char>::id);
! _M_facet_init(new moneypunct_byname<char, false>(__s, 0));
! _M_facet_init(new moneypunct_byname<char, true >(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_replace_facet(locale::_S_classic, &money_get<wchar_t>::id);
_M_replace_facet(locale::_S_classic, &money_put<wchar_t>::id);
! _M_facet_init(new moneypunct_byname<wchar_t, false>(__s, 0));
! _M_facet_init(new moneypunct_byname<wchar_t, true >(__s, 0));
#endif
}
void
! locale::_Impl::_M_construct_numeric(const char* __s)
{
_M_replace_facet(locale::_S_classic, &num_get<char>::id);
_M_replace_facet(locale::_S_classic, &num_put<char>::id);
! _M_facet_init(new numpunct_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
_M_replace_facet(locale::_S_classic, &num_get<wchar_t>::id);
_M_replace_facet(locale::_S_classic, &num_put<wchar_t>::id);
! _M_facet_init(new numpunct_byname<wchar_t>(__s, 0));
#endif
}
void
! locale::_Impl::_M_construct_time(const char* __s)
{
! _M_facet_init(new time_get_byname<char>(__s, 0));
! _M_facet_init(new time_put_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
! _M_facet_init(new time_get_byname<wchar_t>(__s, 0));
! _M_facet_init(new time_put_byname<wchar_t>(__s, 0));
#endif
}
void
! locale::_Impl::_M_construct_messages(const char* __s)
{
! _M_facet_init(new messages_byname<char>(__s, 0));
#ifdef _GLIBCPP_USE_WCHAR_T
! _M_facet_init(new messages_byname<wchar_t>(__s, 0));
#endif
}
}