From: paolo Date: Wed, 6 Oct 2010 00:17:28 +0000 (+0000) Subject: 2010-10-05 David Krauss X-Git-Tag: upstream/4.9.2~26114 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3611e17c9eab6e6ba9f68140748086621b6c9484;p=platform%2Fupstream%2Flinaro-gcc.git 2010-10-05 David Krauss PR libstdc++/45841 * include/bits/fstream.h (basic_filebuf::underflow): Overflow success does not preclude returning failure. (basic_filebuf::pbackfail): Likewise. (basic_filebuf::xsputn): Fix indentation problem. (basic_filebuf::xsgetn): Likewise. Also, add similar overflow call to enable optimized case from write mode. * testsuite/27_io/basic_filebuf/underflow/char/45841.cc: New. * testsuite/27_io/basic_filebuf/underflow/wchar_t/45841.cc: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165009 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ef4ad4d..94aa9f1 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2010-10-05 David Krauss + + PR libstdc++/45841 + * include/bits/fstream.h (basic_filebuf::underflow): Overflow + success does not preclude returning failure. + (basic_filebuf::pbackfail): Likewise. + (basic_filebuf::xsputn): Fix indentation problem. + (basic_filebuf::xsgetn): Likewise. Also, add similar overflow + call to enable optimized case from write mode. + * testsuite/27_io/basic_filebuf/underflow/char/45841.cc: New. + * testsuite/27_io/basic_filebuf/underflow/wchar_t/45841.cc: Likewise. + 2010-10-05 Jonathan Wakely * include/bits/locale_facets_nonio.h (time_get::get_time): Doc typo. diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index 2f661eb..d32de8f 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -207,14 +207,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std) const bool __testin = _M_mode & ios_base::in; if (__testin) { - if (_M_writing) - { - __ret = overflow(); - if (__ret == traits_type::eof()) - return __ret; - _M_set_buffer(-1); - _M_writing = false; - } + if (_M_writing) + { + if (overflow() == traits_type::eof()) + return __ret; + _M_set_buffer(-1); + _M_writing = false; + } // Check for pback madness, and if so switch back to the // normal buffers and jet outta here before expensive // fileops happen... @@ -367,14 +366,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std) const bool __testin = _M_mode & ios_base::in; if (__testin) { - if (_M_writing) - { - __ret = overflow(); - if (__ret == traits_type::eof()) - return __ret; - _M_set_buffer(-1); - _M_writing = false; - } + if (_M_writing) + { + if (overflow() == traits_type::eof()) + return __ret; + _M_set_buffer(-1); + _M_writing = false; + } // Remember whether the pback buffer is active, otherwise below // we may try to store in it a second char (libstdc++/9761). const bool __testpb = _M_pback_init; @@ -545,101 +543,108 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return __elen == __plen; } - template - streamsize - basic_filebuf<_CharT, _Traits>:: - xsgetn(_CharT* __s, streamsize __n) - { - // Clear out pback buffer before going on to the real deal... - streamsize __ret = 0; - if (_M_pback_init) - { - if (__n > 0 && this->gptr() == this->eback()) - { - *__s++ = *this->gptr(); - this->gbump(1); - __ret = 1; - --__n; - } - _M_destroy_pback(); - } - - // Optimization in the always_noconv() case, to be generalized in the - // future: when __n > __buflen we read directly instead of using the - // buffer repeatedly. - const bool __testin = _M_mode & ios_base::in; - const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; - - if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() - && __testin && !_M_writing) - { - // First, copy the chars already present in the buffer. - const streamsize __avail = this->egptr() - this->gptr(); - if (__avail != 0) - { - if (__avail == 1) - *__s = *this->gptr(); - else - traits_type::copy(__s, this->gptr(), __avail); - __s += __avail; - this->gbump(__avail); - __ret += __avail; - __n -= __avail; - } - - // Need to loop in case of short reads (relatively common - // with pipes). - streamsize __len; - for (;;) - { - __len = _M_file.xsgetn(reinterpret_cast(__s), - __n); - if (__len == -1) - __throw_ios_failure(__N("basic_filebuf::xsgetn " - "error reading the file")); - if (__len == 0) - break; - - __n -= __len; - __ret += __len; - if (__n == 0) - break; - - __s += __len; - } - - if (__n == 0) - { - _M_set_buffer(0); - _M_reading = true; - } - else if (__len == 0) - { - // If end of file is reached, set 'uncommitted' - // mode, thus allowing an immediate write without - // an intervening seek. - _M_set_buffer(-1); - _M_reading = false; - } - } - else - __ret += __streambuf_type::xsgetn(__s, __n); + template + streamsize + basic_filebuf<_CharT, _Traits>:: + xsgetn(_CharT* __s, streamsize __n) + { + // Clear out pback buffer before going on to the real deal... + streamsize __ret = 0; + if (_M_pback_init) + { + if (__n > 0 && this->gptr() == this->eback()) + { + *__s++ = *this->gptr(); // emulate non-underflowing sbumpc + this->gbump(1); + __ret = 1; + --__n; + } + _M_destroy_pback(); + } + else if (_M_writing) + { + if (overflow() == traits_type::eof()) + return __ret; + _M_set_buffer(-1); + _M_writing = false; + } + + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n > __buflen we read directly instead of using the + // buffer repeatedly. + const bool __testin = _M_mode & ios_base::in; + const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; + + if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() + && __testin) + { + // First, copy the chars already present in the buffer. + const streamsize __avail = this->egptr() - this->gptr(); + if (__avail != 0) + { + if (__avail == 1) + *__s = *this->gptr(); + else + traits_type::copy(__s, this->gptr(), __avail); + __s += __avail; + this->gbump(__avail); + __ret += __avail; + __n -= __avail; + } + + // Need to loop in case of short reads (relatively common + // with pipes). + streamsize __len; + for (;;) + { + __len = _M_file.xsgetn(reinterpret_cast(__s), + __n); + if (__len == -1) + __throw_ios_failure(__N("basic_filebuf::xsgetn " + "error reading the file")); + if (__len == 0) + break; + + __n -= __len; + __ret += __len; + if (__n == 0) + break; + + __s += __len; + } + + if (__n == 0) + { + _M_set_buffer(0); + _M_reading = true; + } + else if (__len == 0) + { + // If end of file is reached, set 'uncommitted' + // mode, thus allowing an immediate write without + // an intervening seek. + _M_set_buffer(-1); + _M_reading = false; + } + } + else + __ret += __streambuf_type::xsgetn(__s, __n); + + return __ret; + } - return __ret; - } - - template - streamsize - basic_filebuf<_CharT, _Traits>:: - xsputn(const _CharT* __s, streamsize __n) - { - // Optimization in the always_noconv() case, to be generalized in the - // future: when __n is sufficiently large we write directly instead of - // using the buffer. - streamsize __ret = 0; - const bool __testout = _M_mode & ios_base::out; - if (__check_facet(_M_codecvt).always_noconv() - && __testout && !_M_reading) + template + streamsize + basic_filebuf<_CharT, _Traits>:: + xsputn(const _CharT* __s, streamsize __n) + { + streamsize __ret = 0; + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n is sufficiently large we write directly instead of + // using the buffer. + const bool __testout = _M_mode & ios_base::out; + if (__check_facet(_M_codecvt).always_noconv() + && __testout && !_M_reading) { // Measurement would reveal the best choice. const streamsize __chunk = 1ul << 10; @@ -933,7 +938,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { // External position corresponding to gptr(). _M_ext_next = _M_ext_buf - + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, + + _M_codecvt->length(_M_state_last, _M_ext_buf, + _M_ext_next, this->gptr() - this->eback()); const streamsize __remainder = _M_ext_end - _M_ext_next; if (__remainder) diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/char/45841.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/char/45841.cc new file mode 100644 index 0000000..a356d62 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/char/45841.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2010 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, 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 COPYING3. If not see +// . + +// { dg-require-fileio "" } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + using namespace std; + + filebuf fb_in_out; + + fb_in_out.open("tmp_underflow.tst", ios::in | ios::out | ios::trunc); + + VERIFY( fb_in_out.sputc('x') == 'x' ); + VERIFY( fb_in_out.sgetc() == filebuf::traits_type::eof() ); + fb_in_out.close(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/wchar_t/45841.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/wchar_t/45841.cc new file mode 100644 index 0000000..2d7cb7a --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/wchar_t/45841.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2010 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, 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 COPYING3. If not see +// . + +// { dg-require-fileio "" } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + using namespace std; + + wfilebuf fb_in_out; + + fb_in_out.open("tmp_underflow.tst", ios::in | ios::out | ios::trunc); + + VERIFY( fb_in_out.sputc(L'x') == L'x' ); + VERIFY( fb_in_out.sgetc() == wfilebuf::traits_type::eof() ); + fb_in_out.close(); +} + +int main() +{ + test01(); + return 0; +}