From: Paolo Carlini Date: Mon, 24 May 2004 09:40:56 +0000 (+0000) Subject: istream.tcc (ignore): Correctly deal with n == numeric_limits::max(). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b1c5b5a09b545dabdd4a10d67f31d93779af95db;p=gcc.git istream.tcc (ignore): Correctly deal with n == numeric_limits::max(). 2004-05-24 Paolo Carlini * include/bits/istream.tcc (ignore): Correctly deal with n == numeric_limits::max(). * testsuite/27_io/basic_istream/ignore/char/2.cc: New. * include/bits/istream.tcc (basic_istream<>::getline): Prefer '_M_gcount + 1 < __n' to '--__n; _M_gcount < __n', just in case __n == numeric_limits<>::min(). * include/bits/istream.tcc: Minor tweaks. * testsuite/21_strings/basic_string/inserters_extractors/char/10.cc: Tighten. * testsuite/21_strings/basic_string/inserters_extractors/char/11.cc: Likewise. * testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc: Likewise. * testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc: Likewise. * testsuite/27_io/basic_istream/getline/char/5.cc: Likewise. From-SVN: r82198 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9f31df18807..8673f258a65 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,25 @@ +2004-05-24 Paolo Carlini + + * include/bits/istream.tcc (ignore): Correctly deal with + n == numeric_limits::max(). + * testsuite/27_io/basic_istream/ignore/char/2.cc: New. + + * include/bits/istream.tcc (basic_istream<>::getline): Prefer + '_M_gcount + 1 < __n' to '--__n; _M_gcount < __n', just in case + __n == numeric_limits<>::min(). + + * include/bits/istream.tcc: Minor tweaks. + + * testsuite/21_strings/basic_string/inserters_extractors/char/10.cc: + Tighten. + * testsuite/21_strings/basic_string/inserters_extractors/char/11.cc: + Likewise. + * testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc: + Likewise. + * testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc: + Likewise. + * testsuite/27_io/basic_istream/getline/char/5.cc: Likewise. + 2004-05-22 Benjamin Kosnik PR libstdc++/12854 diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc index 52deb6eda4f..6417e951f03 100644 --- a/libstdc++-v3/include/bits/istream.tcc +++ b/libstdc++-v3/include/bits/istream.tcc @@ -519,8 +519,8 @@ namespace std && !traits_type::eq_int_type(__c, __idelim)) { *__s++ = traits_type::to_char_type(__c); - __c = __sb->snextc(); ++_M_gcount; + __c = __sb->snextc(); } if (traits_type::eq_int_type(__c, __eof)) __err |= ios_base::eofbit; @@ -591,15 +591,14 @@ namespace std const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); int_type __c = __sb->sgetc(); - --__n; - while (_M_gcount < __n + while (_M_gcount + 1 < __n && !traits_type::eq_int_type(__c, __eof) && !traits_type::eq_int_type(__c, __idelim)) { streamsize __size = std::min(streamsize(__sb->egptr() - __sb->gptr()), - __n - _M_gcount); + __n - _M_gcount - 1); if (__size > 1) { const char_type* __p = traits_type::find(__sb->gptr(), @@ -616,8 +615,8 @@ namespace std else { *__s++ = traits_type::to_char_type(__c); - __c = __sb->snextc(); ++_M_gcount; + __c = __sb->snextc(); } } @@ -625,8 +624,8 @@ namespace std __err |= ios_base::eofbit; else if (traits_type::eq_int_type(__c, __idelim)) { + ++_M_gcount; __sb->sbumpc(); - ++_M_gcount; } else __err |= ios_base::failbit; @@ -658,7 +657,9 @@ namespace std __streambuf_type* __sb = this->rdbuf(); int_type __c; - while (_M_gcount < __n + if (__n != numeric_limits::max()) + --__n; + while (_M_gcount <= __n && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof)) { ++_M_gcount; @@ -1101,7 +1102,6 @@ namespace std __size_type __extracted = 0; const __size_type __n = __str.max_size(); - bool __testdelim = false; ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); typename __istream_type::sentry __cerb(__in, true); if (__cerb) @@ -1136,8 +1136,8 @@ namespace std __err |= ios_base::eofbit; else if (_Traits::eq_int_type(__c, __idelim)) { + ++__extracted; __sb->sbumpc(); - ++__extracted; } else __err |= ios_base::failbit; diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/10.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/10.cc index 75b7e89d2a5..4822b6b2916 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/10.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/10.cc @@ -38,20 +38,23 @@ string prepare(string::size_type len, unsigned nchunks, char delim) return ret; } -void check(istream& stream, const string& str, char delim) +void check(istream& stream, const string& str, unsigned nchunks, char delim) { bool test __attribute__((unused)) = true; string chunk; string::size_type index = 0, index_new = 0; + unsigned n = 0; while (getline(stream, chunk, delim)) { index_new = str.find(delim, index); VERIFY( !str.compare(index, index_new - index, chunk) ); index = index_new + 1; + ++n; } VERIFY( stream.eof() ); + VERIFY( n == nchunks ); } // istream& getline(istream&, string&, char) @@ -60,7 +63,8 @@ void test01() const char filename[] = "inserters_extractors-2.txt"; const char delim = '|'; - const string data = prepare(777, 10, delim); + const unsigned nchunks = 10; + const string data = prepare(777, nchunks, delim); ofstream ofstrm; ofstrm.open(filename); @@ -69,7 +73,7 @@ void test01() ifstream ifstrm; ifstrm.open(filename); - check(ifstrm, data, delim); + check(ifstrm, data, nchunks, delim); ifstrm.close(); } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/11.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/11.cc index cee596e5b99..e60c441110b 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/11.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/11.cc @@ -38,20 +38,23 @@ string prepare(string::size_type len, unsigned nchunks) return ret; } -void check(istream& stream, const string& str) +void check(istream& stream, const string& str, unsigned nchunks) { bool test __attribute__((unused)) = true; string chunk; string::size_type index = 0, index_new = 0; + unsigned n = 0; while (stream >> chunk) { index_new = str.find(' ', index); VERIFY( !str.compare(index, index_new - index, chunk) ); index = index_new + 1; + ++n; } VERIFY( stream.eof() ); + VERIFY( n == nchunks ); } // istream& operator>>(istream&, string&) @@ -59,7 +62,8 @@ void test01() { const char filename[] = "inserters_extractors-3.txt"; - const string data = prepare(666, 10); + const unsigned nchunks = 10; + const string data = prepare(666, nchunks); ofstream ofstrm; ofstrm.open(filename); @@ -68,7 +72,7 @@ void test01() ifstream ifstrm; ifstrm.open(filename); - check(ifstrm, data); + check(ifstrm, data, nchunks); ifstrm.close(); } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc index 5f1e1d77d9e..ba6bbaf31fa 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc @@ -38,20 +38,23 @@ wstring prepare(wstring::size_type len, unsigned nchunks, wchar_t delim) return ret; } -void check(wistream& stream, const wstring& str, wchar_t delim) +void check(wistream& stream, const wstring& str, unsigned nchunks, wchar_t delim) { bool test __attribute__((unused)) = true; wstring chunk; wstring::size_type index = 0, index_new = 0; + unsigned n = 0; while (getline(stream, chunk, delim)) { index_new = str.find(delim, index); VERIFY( !str.compare(index, index_new - index, chunk) ); index = index_new + 1; + ++n; } VERIFY( stream.eof() ); + VERIFY( n == nchunks ); } // istream& getline(istream&, string&, char) @@ -60,7 +63,8 @@ void test01() const char filename[] = "inserters_extractors-2.txt"; const wchar_t delim = L'|'; - const wstring data = prepare(777, 10, delim); + const unsigned nchunks = 10; + const wstring data = prepare(777, nchunks, delim); wofstream ofstrm; ofstrm.open(filename); @@ -69,7 +73,7 @@ void test01() wifstream ifstrm; ifstrm.open(filename); - check(ifstrm, data, delim); + check(ifstrm, data, nchunks, delim); ifstrm.close(); } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc index ac2e8c3a0e2..66fae676d7a 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/11.cc @@ -38,20 +38,23 @@ wstring prepare(wstring::size_type len, unsigned nchunks) return ret; } -void check(wistream& stream, const wstring& str) +void check(wistream& stream, const wstring& str, unsigned nchunks) { bool test __attribute__((unused)) = true; wstring chunk; wstring::size_type index = 0, index_new = 0; + unsigned n = 0; while (stream >> chunk) { index_new = str.find(L' ', index); VERIFY( !str.compare(index, index_new - index, chunk) ); index = index_new + 1; + ++n; } VERIFY( stream.eof() ); + VERIFY( n == nchunks ); } // istream& operator>>(istream&, string&) @@ -59,7 +62,8 @@ void test01() { const char filename[] = "inserters_extractors-3.txt"; - const wstring data = prepare(666, 10); + const unsigned nchunks = 10; + const wstring data = prepare(666, nchunks); wofstream ofstrm; ofstrm.open(filename); @@ -68,7 +72,7 @@ void test01() wifstream ifstrm; ifstrm.open(filename); - check(ifstrm, data); + check(ifstrm, data, nchunks); ifstrm.close(); } diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/5.cc b/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/5.cc index b2f07725c64..9001f52367c 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/5.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/5.cc @@ -38,12 +38,13 @@ string prepare(string::size_type len, unsigned nchunks, char delim) return ret; } -void check(istream& stream, const string& str, char delim) +void check(istream& stream, const string& str, unsigned nchunks, char delim) { bool test __attribute__((unused)) = true; char buf[1000000]; string::size_type index = 0, index_new = 0; + unsigned n = 0; while (stream.getline(buf, sizeof(buf), delim)) { @@ -51,9 +52,11 @@ void check(istream& stream, const string& str, char delim) VERIFY( stream.gcount() == index_new - index + 1 ); VERIFY( !str.compare(index, index_new - index, buf) ); index = index_new + 1; + ++n; } VERIFY( stream.gcount() == 0 ); VERIFY( stream.eof() ); + VERIFY( n == nchunks ); } void test01() @@ -61,7 +64,8 @@ void test01() const char filename[] = "istream_getline.txt"; const char delim = '|'; - const string data = prepare(777, 10, delim); + const unsigned nchunks = 10; + const string data = prepare(777, nchunks, delim); ofstream ofstrm; ofstrm.open(filename); @@ -70,7 +74,7 @@ void test01() ifstream ifstrm; ifstrm.open(filename); - check(ifstrm, data, delim); + check(ifstrm, data, nchunks, delim); ifstrm.close(); } diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/2.cc new file mode 100644 index 00000000000..85bdbfc2ed7 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/2.cc @@ -0,0 +1,84 @@ +// Copyright (C) 2004 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.6.1.3 unformatted input functions + +#include +#include +#include +#include +#include + +using namespace std; + +string prepare(string::size_type len, unsigned nchunks, char delim) +{ + string ret; + for (unsigned i = 0; i < nchunks; ++i) + { + for (string::size_type j = 0; j < len; ++j) + ret.push_back('a' + rand() % 26); + len *= 2; + ret.push_back(delim); + } + return ret; +} + +void check(istream& stream, const string& str, unsigned nchunks, char delim) +{ + bool test __attribute__((unused)) = true; + + string::size_type index = 0, index_new = 0; + unsigned n = 0; + + while (stream.ignore(numeric_limits::max(), delim).good()) + { + index_new = str.find(delim, index); + VERIFY( stream.gcount() == index_new - index + 1 ); + index = index_new + 1; + ++n; + } + VERIFY( stream.gcount() == 0 ); + VERIFY( !stream.fail() ); + VERIFY( n == nchunks ); +} + +void test01() +{ + const char filename[] = "istream_ignore.txt"; + + const char delim = '|'; + const unsigned nchunks = 10; + const string data = prepare(555, nchunks, delim); + + ofstream ofstrm; + ofstrm.open(filename); + ofstrm.write(data.data(), data.size()); + ofstrm.close(); + + ifstream ifstrm; + ifstrm.open(filename); + check(ifstrm, data, nchunks, delim); + ifstrm.close(); +} + +int main() +{ + test01(); + return 0; +}