From 6f4d3d86564db6a42ffb8ffa8960cc32129ab581 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 10 Feb 2006 18:29:04 +0000 Subject: [PATCH] re PR libstdc++/26181 (istream::operator>>(streambuf*) fails to set eofbit) 2006-10-02 Paolo Carlini PR libstdc++/26181 * include/bits/streambuf.tcc (__copy_streambufs_eof): New, like the existing __copy_streambufs but reporting eof in input. (__copy_streambufs): Just use the latter. * src/streambuf.cc (__copy_streambufs_eof): Adjust specializations of __copy_streambufs. * include/bits/istream.tcc (operator>>(__streambuf_type*)): Use __copy_streambufs_eof instead. * include/std/std_streambuf.h: Adjust. * src/streambuf-inst.cc: Adjust. * config/abi/pre/gnu.ver: Export the new symbols. * testsuite/27_io/basic_istream/extractors_other/char/26181.cc: New. * testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc: Likewise. * testsuite/27_io/basic_istream/extractors_other/char/1.cc: Adjust. * testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc: Likewise. From-SVN: r110841 --- libstdc++-v3/ChangeLog | 20 ++++++++ libstdc++-v3/config/abi/pre/gnu.ver | 4 +- libstdc++-v3/include/bits/istream.tcc | 5 +- libstdc++-v3/include/bits/streambuf.tcc | 36 ++++++++++--- libstdc++-v3/include/std/std_streambuf.h | 19 +++---- libstdc++-v3/src/streambuf-inst.cc | 16 ++++-- libstdc++-v3/src/streambuf.cc | 32 ++++++++---- .../basic_istream/extractors_other/char/1.cc | 7 +-- .../extractors_other/char/26181.cc | 50 +++++++++++++++++++ .../extractors_other/wchar_t/1.cc | 6 +-- .../extractors_other/wchar_t/26181.cc | 50 +++++++++++++++++++ 11 files changed, 210 insertions(+), 35 deletions(-) create mode 100644 libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/26181.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 38ae3c72c74..85fe6bbc679 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2006-10-02 Paolo Carlini + + PR libstdc++/26181 + * include/bits/streambuf.tcc (__copy_streambufs_eof): New, like + the existing __copy_streambufs but reporting eof in input. + (__copy_streambufs): Just use the latter. + * src/streambuf.cc (__copy_streambufs_eof): Adjust specializations + of __copy_streambufs. + * include/bits/istream.tcc (operator>>(__streambuf_type*)): Use + __copy_streambufs_eof instead. + * include/std/std_streambuf.h: Adjust. + * src/streambuf-inst.cc: Adjust. + * config/abi/pre/gnu.ver: Export the new symbols. + * testsuite/27_io/basic_istream/extractors_other/char/26181.cc: New. + * testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc: + Likewise. + * testsuite/27_io/basic_istream/extractors_other/char/1.cc: Adjust. + * testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc: + Likewise. + 2006-02-08 Benjamin Kosnik PR libstdc++/26142 diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 8ea7c64a525..c756290df58 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -1,6 +1,6 @@ ## Linker script for GNU versioning (GNU ld 2.13.91+ only.) ## -## Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +## Copyright (C) 2002, 2003, 2004, 2005, 2006 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 @@ -673,6 +673,8 @@ GLIBCXX_3.4.7 { _ZNSi10_M_extractI[^g]*; _ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractI[^g]*; + _ZSt21__copy_streambufs_eofI[cw]St11char_traitsI[cw]EEiPSt15basic_streambuf*; + } GLIBCXX_3.4.6; # Symbols in the support library (libsupc++) have their own tag. diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc index 5b5da65aaf5..ef773bc7080 100644 --- a/libstdc++-v3/include/bits/istream.tcc +++ b/libstdc++-v3/include/bits/istream.tcc @@ -183,8 +183,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { try { - if (!__copy_streambufs(this->rdbuf(), __sbout)) + bool __ineof; + if (!__copy_streambufs_eof(this->rdbuf(), __sbout, __ineof)) __err |= ios_base::failbit; + if (__ineof) + __err |= ios_base::eofbit; } catch(...) { this->_M_setstate(ios_base::failbit); } diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc index b1a4876fded..c4b860549a7 100644 --- a/libstdc++-v3/include/bits/streambuf.tcc +++ b/libstdc++-v3/include/bits/streambuf.tcc @@ -1,6 +1,6 @@ // Stream buffer classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -117,22 +117,36 @@ _GLIBCXX_BEGIN_NAMESPACE(std) // standard. template streamsize - __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, - basic_streambuf<_CharT, _Traits>* __sbout) + __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout, + bool& __ineof) { streamsize __ret = 0; + __ineof = true; typename _Traits::int_type __c = __sbin->sgetc(); while (!_Traits::eq_int_type(__c, _Traits::eof())) { __c = __sbout->sputc(_Traits::to_char_type(__c)); if (_Traits::eq_int_type(__c, _Traits::eof())) - break; + { + __ineof = false; + break; + } ++__ret; __c = __sbin->snextc(); } return __ret; } + template + inline streamsize + __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout) + { + bool __ineof; + return __copy_streambufs_eof(__sbin, __sbout, __ineof); + } + // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. @@ -140,13 +154,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std) extern template class basic_streambuf; extern template streamsize - __copy_streambufs(basic_streambuf*, basic_streambuf*); + __copy_streambufs(basic_streambuf*, + basic_streambuf*); + extern template + streamsize + __copy_streambufs_eof(basic_streambuf*, + basic_streambuf*, bool&); #ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_streambuf; extern template streamsize - __copy_streambufs(basic_streambuf*, basic_streambuf*); + __copy_streambufs(basic_streambuf*, + basic_streambuf*); + extern template + streamsize + __copy_streambufs_eof(basic_streambuf*, + basic_streambuf*, bool&); #endif #endif diff --git a/libstdc++-v3/include/std/std_streambuf.h b/libstdc++-v3/include/std/std_streambuf.h index f59e7deb9a2..b36a139b978 100644 --- a/libstdc++-v3/include/std/std_streambuf.h +++ b/libstdc++-v3/include/std/std_streambuf.h @@ -1,6 +1,6 @@ // Stream buffer classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -55,8 +55,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ template streamsize - __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, - basic_streambuf<_CharT, _Traits>* __sbout); + __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout, + bool& __ineof); /** * @brief The actual work of input and output (interface). @@ -151,8 +152,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) friend class ostreambuf_iterator; friend streamsize - __copy_streambufs<>(__streambuf_type* __sbin, - __streambuf_type* __sbout); + __copy_streambufs_eof<>(__streambuf_type* __sbin, + __streambuf_type* __sbout, bool& __ineof); template friend basic_istream<_CharT2, _Traits2>& @@ -792,13 +793,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std) // Explicit specialization declarations, defined in src/streambuf.cc. template<> streamsize - __copy_streambufs(basic_streambuf* __sbin, - basic_streambuf* __sbout); + __copy_streambufs_eof(basic_streambuf* __sbin, + basic_streambuf* __sbout, bool& __ineof); #ifdef _GLIBCXX_USE_WCHAR_T template<> streamsize - __copy_streambufs(basic_streambuf* __sbin, - basic_streambuf* __sbout); + __copy_streambufs_eof(basic_streambuf* __sbin, + basic_streambuf* __sbout, bool& __ineof); #endif _GLIBCXX_END_NAMESPACE diff --git a/libstdc++-v3/src/streambuf-inst.cc b/libstdc++-v3/src/streambuf-inst.cc index d08bc0d2db1..38fb0d4c3fa 100644 --- a/libstdc++-v3/src/streambuf-inst.cc +++ b/libstdc++-v3/src/streambuf-inst.cc @@ -1,6 +1,6 @@ // Explicit instantiation file. -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2005 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -42,7 +42,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template streamsize - __copy_streambufs(basic_streambuf*, basic_streambuf*); + __copy_streambufs(basic_streambuf*, basic_streambuf*); + + template + streamsize + __copy_streambufs_eof(basic_streambuf*, + basic_streambuf*, bool&); #ifdef _GLIBCXX_USE_WCHAR_T // wstreambuf @@ -50,7 +55,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template streamsize - __copy_streambufs(basic_streambuf*, basic_streambuf*); + __copy_streambufs(basic_streambuf*, basic_streambuf*); + + template + streamsize + __copy_streambufs_eof(basic_streambuf*, + basic_streambuf*, bool&); #endif _GLIBCXX_END_NAMESPACE diff --git a/libstdc++-v3/src/streambuf.cc b/libstdc++-v3/src/streambuf.cc index 75f61cca4c9..31863145f75 100644 --- a/libstdc++-v3/src/streambuf.cc +++ b/libstdc++-v3/src/streambuf.cc @@ -1,6 +1,6 @@ // Stream buffer classes -*- C++ -*- -// Copyright (C) 2004, 2005 Free Software Foundation, Inc. +// Copyright (C) 2004, 2005, 2006 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 @@ -37,11 +37,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template<> streamsize - __copy_streambufs(basic_streambuf* __sbin, - basic_streambuf* __sbout) + __copy_streambufs_eof(basic_streambuf* __sbin, + basic_streambuf* __sbout, bool& __ineof) { typedef basic_streambuf::traits_type traits_type; streamsize __ret = 0; + __ineof = true; traits_type::int_type __c = __sbin->sgetc(); while (!traits_type::eq_int_type(__c, traits_type::eof())) { @@ -52,14 +53,20 @@ _GLIBCXX_BEGIN_NAMESPACE(std) __sbin->gbump(__wrote); __ret += __wrote; if (__wrote < __n) - break; + { + __ineof = false; + break; + } __c = __sbin->underflow(); } else { __c = __sbout->sputc(traits_type::to_char_type(__c)); if (traits_type::eq_int_type(__c, traits_type::eof())) - break; + { + __ineof = false; + break; + } ++__ret; __c = __sbin->snextc(); } @@ -70,11 +77,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std) #ifdef _GLIBCXX_USE_WCHAR_T template<> streamsize - __copy_streambufs(basic_streambuf* __sbin, - basic_streambuf* __sbout) + __copy_streambufs_eof(basic_streambuf* __sbin, + basic_streambuf* __sbout, bool& __ineof) { typedef basic_streambuf::traits_type traits_type; streamsize __ret = 0; + __ineof = true; traits_type::int_type __c = __sbin->sgetc(); while (!traits_type::eq_int_type(__c, traits_type::eof())) { @@ -85,14 +93,20 @@ _GLIBCXX_BEGIN_NAMESPACE(std) __sbin->gbump(__wrote); __ret += __wrote; if (__wrote < __n) - break; + { + __ineof = false; + break; + } __c = __sbin->underflow(); } else { __c = __sbout->sputc(traits_type::to_char_type(__c)); if (traits_type::eq_int_type(__c, traits_type::eof())) - break; + { + __ineof = false; + break; + } ++__ret; __c = __sbin->snextc(); } diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/1.cc index 8994d7397f2..a2a69bb53ca 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/1.cc @@ -1,6 +1,7 @@ // 1999-07-28 bkoz -// Copyright (C) 1999, 2001, 2003 Free Software Foundation +// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +// Free Software Foundation // // 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 @@ -124,9 +125,9 @@ void test01() state1 = is_04.rdstate(); is_04 >> &isbuf_03; state2 = is_04.rdstate(); - VERIFY( state1 == state2 ); + VERIFY( state1 != state2 ); VERIFY( !static_cast(state2 & statefail) ); - VERIFY( state2 != stateeof ); + VERIFY( state2 == stateeof ); strtmp = isbuf_03.str(); VERIFY( strtmp == str_02 ); // as only an "in" buffer VERIFY( isbuf_03.sgetc() == 'a' ); diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/26181.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/26181.cc new file mode 100644 index 00000000000..b478e9699bb --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/26181.cc @@ -0,0 +1,50 @@ +// Copyright (C) 2006 Free Software Foundation +// +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +#include +#include +#include + +// libstdc++/26181 +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + typedef istringstream::pos_type pos_type; + + istringstream iss("Territoires de l'Oubli"); + ostringstream oss; + + VERIFY( iss.tellg() == pos_type(0) ); + + iss >> oss.rdbuf(); + VERIFY( iss.rdstate() == iss.eofbit ); + + iss.clear(); + VERIFY( iss.tellg() == pos_type(22) ); + + iss.get(); + VERIFY( iss.tellg() == pos_type(-1) ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc index 8c59d46553d..1766169fea7 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2004 Free Software Foundation +// Copyright (C) 2004, 2005, 2006 Free Software Foundation // // 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 @@ -122,9 +122,9 @@ void test01() state1 = is_04.rdstate(); is_04 >> &isbuf_03; state2 = is_04.rdstate(); - VERIFY( state1 == state2 ); + VERIFY( state1 != state2 ); VERIFY( !static_cast(state2 & statefail) ); - VERIFY( state2 != stateeof ); + VERIFY( state2 == stateeof ); strtmp = isbuf_03.str(); VERIFY( strtmp == str_02 ); // as only an "in" buffer VERIFY( isbuf_03.sgetc() == L'a' ); diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc new file mode 100644 index 00000000000..4fbace705b1 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc @@ -0,0 +1,50 @@ +// Copyright (C) 2006 Free Software Foundation +// +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +#include +#include +#include + +// libstdc++/26181 +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + typedef wistringstream::pos_type pos_type; + + wistringstream iss(L"Territoires de l'Oubli"); + wostringstream oss; + + VERIFY( iss.tellg() == pos_type(0) ); + + iss >> oss.rdbuf(); + VERIFY( iss.rdstate() == iss.eofbit ); + + iss.clear(); + VERIFY( iss.tellg() == pos_type(22) ); + + iss.get(); + VERIFY( iss.tellg() == pos_type(-1) ); +} + +int main() +{ + test01(); + return 0; +}