This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] libstdc++/38678
- From: Paolo Carlini <paolo dot carlini at oracle dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Thu, 01 Jan 2009 11:09:55 +0100
- Subject: [v3] libstdc++/38678
Hi,
tested x86_64-linux, committed to mainline.
Paolo.
PS: Happy New Year!
///////////////
2009-01-01 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/38678
* include/std/istream (basic_istream<>::_M_read): New.
* include/bits/istream.tcc (basic_istream<>::_M_read): Define.
(basic_istream<>::read, basic_istream<>::readsome): Use it.
* include/std/ostream (basic_ostream<>::_M_write_): New.
(basic_ostream<>::_M_write): Adjust.
* include/bits/ostream.tcc (basic_ostream<>::_M_write_): Define.
* testsuite/27_io/basic_istream/read/char/38678.cc: New.
* testsuite/27_io/basic_istream/read/wchar_t/38678.cc: Likewise.
* testsuite/27_io/basic_ostream/write/char/38678.cc: Likewise.
* testsuite/27_io/basic_ostream/write/wchar_t/38678.cc: Likewise.
Index: include/std/istream
===================================================================
*** include/std/istream (revision 142977)
--- include/std/istream (working copy)
***************
*** 1,7 ****
// Input streams -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! // 2006, 2007, 2008
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
--- 1,7 ----
// Input streams -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! // 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 586,596 ****
--- 586,613 ----
: _M_gcount(streamsize(0))
{ this->init(0); }
+ streamsize
+ _M_read(char_type* __s, streamsize __n);
+
template<typename _ValueT>
__istream_type&
_M_extract(_ValueT& __v);
};
+ template<>
+ inline streamsize
+ basic_istream<char>::
+ _M_read(char_type* __s, streamsize __n)
+ { return this->rdbuf()->__streambuf_type::xsgetn(__s, __n); }
+
+ #ifdef _GLIBCXX_USE_WCHAR_T
+ template<>
+ inline streamsize
+ basic_istream<wchar_t>::
+ _M_read(char_type* __s, streamsize __n)
+ { return this->rdbuf()->__streambuf_type::xsgetn(__s, __n); }
+ #endif
+
// Explicit specialization declarations, defined in src/istream.cc.
template<>
basic_istream<char>&
Index: include/std/ostream
===================================================================
*** include/std/ostream (revision 142977)
--- include/std/ostream (working copy)
***************
*** 1,7 ****
// Output streams -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! // 2006, 2007, 2008
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
--- 1,7 ----
// Output streams -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! // 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 286,300 ****
__ostream_type&
put(char_type __c);
- // Core write functionality, without sentry.
- void
- _M_write(const char_type* __s, streamsize __n)
- {
- const streamsize __put = this->rdbuf()->sputn(__s, __n);
- if (__put != __n)
- this->setstate(ios_base::badbit);
- }
-
/**
* @brief Character string insertion.
* @param s The array to insert.
--- 286,291 ----
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 365,375 ****
--- 356,391 ----
basic_ostream()
{ this->init(0); }
+ void
+ _M_write(const char_type* __s, streamsize __n)
+ {
+ const streamsize __put = _M_write_(__s, __n);
+ if (__put != __n)
+ this->setstate(ios_base::badbit);
+ }
+
+ streamsize
+ _M_write_(const char_type* __s, streamsize __n);
+
template<typename _ValueT>
__ostream_type&
_M_insert(_ValueT __v);
};
+ template<>
+ inline streamsize
+ basic_ostream<char>::
+ _M_write_(const char_type* __s, streamsize __n)
+ { return this->rdbuf()->__streambuf_type::xsputn(__s, __n); }
+
+ #ifdef _GLIBCXX_USE_WCHAR_T
+ template<>
+ inline streamsize
+ basic_ostream<wchar_t>::
+ _M_write_(const char_type* __s, streamsize __n)
+ { return this->rdbuf()->__streambuf_type::xsputn(__s, __n); }
+ #endif
+
/**
* @brief Performs setup work for output streams.
*
Index: include/bits/istream.tcc
===================================================================
*** include/bits/istream.tcc (revision 142977)
--- include/bits/istream.tcc (working copy)
***************
*** 1,7 ****
// istream classes -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! // 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
--- 1,7 ----
// istream classes -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! // 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 600,605 ****
--- 600,621 ----
}
template<typename _CharT, typename _Traits>
+ streamsize
+ basic_istream<_CharT, _Traits>::
+ _M_read(char_type* __s, streamsize __n)
+ {
+ streamsize __ret = 0;
+ for (; __ret < __n; ++__ret, ++__s)
+ {
+ const int_type __c = this->rdbuf()->sbumpc();
+ if (traits_type::eq_int_type(__c, traits_type::eof()))
+ break;
+ traits_type::assign(*__s, traits_type::to_char_type(__c));
+ }
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::
read(char_type* __s, streamsize __n)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 611,617 ****
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
! _M_gcount = this->rdbuf()->sgetn(__s, __n);
if (_M_gcount != __n)
__err |= (ios_base::eofbit | ios_base::failbit);
}
--- 627,633 ----
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
! _M_gcount = _M_read(__s, __n);
if (_M_gcount != __n)
__err |= (ios_base::eofbit | ios_base::failbit);
}
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 643,649 ****
// Cannot compare int_type with streamsize generically.
const streamsize __num = this->rdbuf()->in_avail();
if (__num > 0)
! _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n));
else if (__num == -1)
__err |= ios_base::eofbit;
}
--- 659,665 ----
// Cannot compare int_type with streamsize generically.
const streamsize __num = this->rdbuf()->in_avail();
if (__num > 0)
! _M_gcount = _M_read(__s, std::min(__num, __n));
else if (__num == -1)
__err |= ios_base::eofbit;
}
Index: include/bits/ostream.tcc
===================================================================
*** include/bits/ostream.tcc (revision 142977)
--- include/bits/ostream.tcc (working copy)
***************
*** 1,7 ****
// ostream classes -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! // 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
--- 1,7 ----
// ostream classes -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
! // 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 183,188 ****
--- 183,203 ----
}
template<typename _CharT, typename _Traits>
+ streamsize
+ basic_ostream<_CharT, _Traits>::
+ _M_write_(const char_type* __s, streamsize __n)
+ {
+ streamsize __ret = 0;
+ for (; __ret < __n; ++__ret, ++__s)
+ {
+ const int_type __c = this->rdbuf()->sputc(*__s);
+ if (traits_type::eq_int_type(__c, traits_type::eof()))
+ break;
+ }
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
write(const _CharT* __s, streamsize __n)
Index: testsuite/27_io/basic_istream/read/wchar_t/38678.cc
===================================================================
*** testsuite/27_io/basic_istream/read/wchar_t/38678.cc (revision 0)
--- testsuite/27_io/basic_istream/read/wchar_t/38678.cc (revision 0)
***************
*** 0 ****
--- 1,67 ----
+ // Copyright (C) 2009 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.
+
+ // 27.6.1.3 unformatted input functions
+
+ #include <istream>
+ #include <streambuf>
+ #include <testsuite_hooks.h>
+
+ // libstdc++/38678
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+
+ static wchar_t x = L'0';
+
+ struct : std::wstreambuf
+ {
+ wchar_t c;
+
+ int_type
+ underflow()
+ {
+ c = x++;
+ setg(&c, &c, &c + 1);
+ return traits_type::to_int_type(c);
+ }
+
+ std::streamsize
+ xsgetn(wchar_t*, std::streamsize)
+ {
+ VERIFY( !"xsgetn should not be called" );
+ return 0;
+ }
+ } sb;
+
+ std::wistream in(&sb);
+
+ wchar_t s[4] = L"";
+
+ in.read(s, 4);
+
+ VERIFY( in.good() );
+ VERIFY( 4 == in.gcount() );
+ VERIFY( L'0' == s[0] && L'1' == s[1] && L'2' == s[2] && L'3' == s[3] );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
Index: testsuite/27_io/basic_istream/read/char/38678.cc
===================================================================
*** testsuite/27_io/basic_istream/read/char/38678.cc (revision 0)
--- testsuite/27_io/basic_istream/read/char/38678.cc (revision 0)
***************
*** 0 ****
--- 1,67 ----
+ // Copyright (C) 2009 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.
+
+ // 27.6.1.3 unformatted input functions
+
+ #include <istream>
+ #include <streambuf>
+ #include <testsuite_hooks.h>
+
+ // libstdc++/38678
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+
+ static char x = '0';
+
+ struct : std::streambuf
+ {
+ char c;
+
+ int_type
+ underflow()
+ {
+ c = x++;
+ setg(&c, &c, &c + 1);
+ return traits_type::to_int_type(c);
+ }
+
+ std::streamsize
+ xsgetn(char*, std::streamsize)
+ {
+ VERIFY( !"xsgetn should not be called" );
+ return 0;
+ }
+ } sb;
+
+ std::istream in(&sb);
+
+ char s[4] = "";
+
+ in.read(s, 4);
+
+ VERIFY( in.good() );
+ VERIFY( 4 == in.gcount() );
+ VERIFY( '0' == s[0] && '1' == s[1] && '2' == s[2] && '3' == s[3] );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
Index: testsuite/27_io/basic_ostream/write/wchar_t/38678.cc
===================================================================
*** testsuite/27_io/basic_ostream/write/wchar_t/38678.cc (revision 0)
--- testsuite/27_io/basic_ostream/write/wchar_t/38678.cc (revision 0)
***************
*** 0 ****
--- 1,63 ----
+ // Copyright (C) 2009 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.
+
+ // 27.6.2.6 unformatted output functions
+
+ #include <ostream>
+ #include <streambuf>
+ #include <testsuite_hooks.h>
+
+ // libstdc++/38678
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+
+ static wchar_t s[4] = L"";
+ static unsigned i = 0;
+
+ struct : std::wstreambuf
+ {
+ int_type
+ overflow(int_type c)
+ {
+ s[i++] = traits_type::to_char_type(c);
+ return traits_type::not_eof(c);
+ }
+
+ std::streamsize
+ xsputn(const wchar_t*, std::streamsize)
+ {
+ VERIFY( !"xsputn should not be called" );
+ return 0;
+ }
+ } sb;
+
+ std::wostream out(&sb);
+
+ out.write(L"0123", 4);
+
+ VERIFY( out.good() );
+ VERIFY( 4 == i );
+ VERIFY( L'0' == s[0] && L'1' == s[1] && L'2' == s[2] && L'3' == s[3] );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
Index: testsuite/27_io/basic_ostream/write/char/38678.cc
===================================================================
*** testsuite/27_io/basic_ostream/write/char/38678.cc (revision 0)
--- testsuite/27_io/basic_ostream/write/char/38678.cc (revision 0)
***************
*** 0 ****
--- 1,63 ----
+ // Copyright (C) 2009 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.
+
+ // 27.6.2.6 unformatted output functions
+
+ #include <ostream>
+ #include <streambuf>
+ #include <testsuite_hooks.h>
+
+ // libstdc++/38678
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+
+ static char s[4] = "";
+ static unsigned i = 0;
+
+ struct : std::streambuf
+ {
+ int_type
+ overflow(int_type c)
+ {
+ s[i++] = traits_type::to_char_type(c);
+ return traits_type::not_eof(c);
+ }
+
+ std::streamsize
+ xsputn(const char*, std::streamsize)
+ {
+ VERIFY( !"xsputn should not be called" );
+ return 0;
+ }
+ } sb;
+
+ std::ostream out(&sb);
+
+ out.write("0123", 4);
+
+ VERIFY( out.good() );
+ VERIFY( 4 == i );
+ VERIFY( '0' == s[0] && '1' == s[1] && '2' == s[2] && '3' == s[3] );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }