diff options
-rw-r--r-- | libstdc++-v3/include/bits/istream.tcc | 44 | ||||
-rw-r--r-- | libstdc++-v3/src/c++98/compatibility.cc | 32 | ||||
-rw-r--r-- | libstdc++-v3/src/c++98/istream.cc | 56 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/94749.cc | 151 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/96161.cc | 79 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc | 155 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/96161.cc | 79 |
7 files changed, 561 insertions, 35 deletions
diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc index d36374c..5983e51 100644 --- a/libstdc++-v3/include/bits/istream.tcc +++ b/libstdc++-v3/include/bits/istream.tcc @@ -538,11 +538,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION break; } - if (__large_ignore) - _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; + if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max) + { + if (__large_ignore) + _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; - if (traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + else if (_M_gcount < __n) + { + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } } __catch(__cxxabiv1::__forced_unwind&) { @@ -596,15 +604,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION break; } - if (__large_ignore) - _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; + if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max) + { + if (__large_ignore) + _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; - if (traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - else if (_M_gcount < __n) // implies __c == __delim + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else + { + if (_M_gcount != __n) + ++_M_gcount; + __sb->sbumpc(); + } + } + else if (_M_gcount < __n) // implies __c == __delim or EOF { - ++_M_gcount; - __sb->sbumpc(); + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else + { + ++_M_gcount; + __sb->sbumpc(); + } } } __catch(__cxxabiv1::__forced_unwind&) diff --git a/libstdc++-v3/src/c++98/compatibility.cc b/libstdc++-v3/src/c++98/compatibility.cc index 4e95b7e..6024bb9 100644 --- a/libstdc++-v3/src/c++98/compatibility.cc +++ b/libstdc++-v3/src/c++98/compatibility.cc @@ -107,11 +107,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION break; } - if (__large_ignore) - _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; + if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max) + { + if (__large_ignore) + _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; - if (traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + else if (_M_gcount < __n) + { + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } } __catch(__cxxabiv1::__forced_unwind&) { @@ -178,11 +186,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION break; } - if (__large_ignore) - _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; + if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max) + { + if (__large_ignore) + _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; - if (traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + else if (_M_gcount < __n) + { + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } } __catch(__cxxabiv1::__forced_unwind&) { diff --git a/libstdc++-v3/src/c++98/istream.cc b/libstdc++-v3/src/c++98/istream.cc index d6fee1a..d2c6794 100644 --- a/libstdc++-v3/src/c++98/istream.cc +++ b/libstdc++-v3/src/c++98/istream.cc @@ -166,15 +166,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION break; } - if (__large_ignore) - _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; + if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max) + { + if (__large_ignore) + _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; - if (traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - else if (_M_gcount < __n) // implies __c == __delim + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else + { + if (_M_gcount != __n) + ++_M_gcount; + __sb->sbumpc(); + } + } + else if (_M_gcount < __n) // implies __c == __delim or EOF { - ++_M_gcount; - __sb->sbumpc(); + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else + { + ++_M_gcount; + __sb->sbumpc(); + } } } __catch(__cxxabiv1::__forced_unwind&) @@ -406,15 +420,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION break; } - if (__large_ignore) - _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; + if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max) + { + if (__large_ignore) + _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; - if (traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - else if (_M_gcount < __n) // implies __c == __delim + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else + { + if (_M_gcount != __n) + ++_M_gcount; + __sb->sbumpc(); + } + } + else if (_M_gcount < __n) // implies __c == __delim or EOF { - ++_M_gcount; - __sb->sbumpc(); + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else + { + ++_M_gcount; + __sb->sbumpc(); + } } } __catch(__cxxabiv1::__forced_unwind&) diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/94749.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/94749.cc index 03b5286..32b604d 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/94749.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/94749.cc @@ -16,11 +16,13 @@ // <http://www.gnu.org/licenses/>. // { dg-do run } +// { dg-options "-DSIMULATOR_TEST" { target simulator } } // PR libstdc++/94749 // basic_istream::ignore(n, c) discards n+1 if next character is equal to c. #include <sstream> +#include <limits> #include <testsuite_hooks.h> typedef char C; @@ -30,8 +32,10 @@ test01() { std::basic_istringstream<C> s(" + -"); s.ignore(1, '+'); + VERIFY( s.gcount() == 1 ); VERIFY( s.get() == '+' ); s.ignore(3, '-'); + VERIFY( s.gcount() == 3 ); VERIFY( s.get() == '-' ); } @@ -40,8 +44,10 @@ test02() { std::basic_istringstream<C> s(".+...-"); s.ignore(1, '+'); + VERIFY( s.gcount() == 1 ); VERIFY( s.get() == '+' ); s.ignore(3, '-'); + VERIFY( s.gcount() == 3 ); VERIFY( s.get() == '-' ); } @@ -50,8 +56,10 @@ test03() { std::basic_istringstream<C, __gnu_cxx::char_traits<C> > s(" + -"); s.ignore(1, '+'); + VERIFY( s.gcount() == 1 ); VERIFY( s.get() == '+' ); s.ignore(3, '-'); + VERIFY( s.gcount() == 3 ); VERIFY( s.get() == '-' ); } @@ -60,11 +68,150 @@ test04() { std::basic_istringstream<C, __gnu_cxx::char_traits<C> > s(".+...-"); s.ignore(1, '+'); + VERIFY( s.gcount() == 1 ); VERIFY( s.get() == '+' ); s.ignore(3, '-'); + VERIFY( s.gcount() == 3 ); VERIFY( s.get() == '-' ); } +// The original fix for PR libstdc++/94749 failed to discard the delimiter +// if it occurred after numeric_limits<streamsize>::max() had been seen. +// This streambuf will keep filling the get area with zero bytes until +// almost numeric_limits<streamsize>::max() characters have been read, +// and then return one more buffer that has "123" at its end. +template<typename T> +struct buff : std::basic_streambuf<typename T::char_type, T> +{ + typedef typename T::char_type char_type; + typedef typename T::int_type int_type; + typedef std::streamsize streamsize; + typedef std::numeric_limits<streamsize> limits; + + buff() : count(0), buf() { } + + int_type underflow() + { + // Number of characters left until we overflow the counter + const streamsize headroom = limits::max() - count; + + if (headroom == 0) + return T::eof(); + + if (bufsz < headroom) + { + this->setg(buf, buf, buf + bufsz); + count += bufsz; + } + else + { + // write "123" across the 2GB boundary + buf[headroom-1] = '1'; + buf[headroom+0] = '2'; + buf[headroom+1] = '3'; + this->setg(buf, buf, buf + headroom + 2); + count = limits::max(); + } + + return buf[0]; + } + + streamsize count; + + static const streamsize bufsz = 2048 << limits::digits10; + char_type buf[bufsz + 2]; +}; + +void +test05() +{ + // Not possible to overflow 64-bit streamsize in reasonable time. + if (std::numeric_limits<std::streamsize>::digits > 32) + return; + + typedef std::char_traits<C> T; + + std::basic_istream<C, T> in(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), '1'); + VERIFY(in.good()); + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == '2'); + VERIFY(in.get() == '3'); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), '2'); + VERIFY(in.good()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == '3'); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), '3'); + VERIFY(in.good()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), '4'); + VERIFY(in.eof()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(nullptr); +} + +void +test06() +{ + if (std::numeric_limits<std::streamsize>::digits > 32) + return; + + typedef __gnu_cxx::char_traits<C> T; + + std::basic_istream<C, T> in(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), '1'); + VERIFY(in.good()); + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == '2'); + VERIFY(in.get() == '3'); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), '2'); + VERIFY(in.good()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == '3'); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), '3'); + VERIFY(in.good()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), '4'); + VERIFY(in.eof()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(nullptr); +} int main() @@ -73,4 +220,8 @@ main() test02(); test03(); test04(); + test05(); +#ifndef SIMULATOR_TEST + test06(); +#endif } diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/96161.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/96161.cc new file mode 100644 index 0000000..c19e5f9 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/96161.cc @@ -0,0 +1,79 @@ +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run } + +// PR libstdc++/96161 +// basic_istream::ignore sets eofbit too soon + +#include <sstream> +#include <limits> +#include <testsuite_hooks.h> + +typedef char C; + +void +test01() +{ + std::basic_istringstream<C> s(" "); + s.ignore(2, '+'); + VERIFY( s.gcount() == 2 ); + VERIFY( s.good() ); + VERIFY( s.get() == std::char_traits<C>::eof() ); + VERIFY( s.eof() ); +} + +void +test02() +{ + std::basic_istringstream<C> s(" "); + s.ignore(2); + VERIFY( s.gcount() == 2 ); + VERIFY( s.good() ); + VERIFY( s.get() == std::char_traits<C>::eof() ); + VERIFY( s.eof() ); +} + +void +test03() +{ + std::basic_istringstream<C, __gnu_cxx::char_traits<C> > s(" "); + s.ignore(2, '+'); + VERIFY( s.gcount() == 2 ); + VERIFY( s.good() ); + VERIFY( s.get() == __gnu_cxx::char_traits<C>::eof() ); + VERIFY( s.eof() ); +} + +void +test04() +{ + std::basic_istringstream<C, __gnu_cxx::char_traits<C> > s(" "); + s.ignore(2); + VERIFY( s.gcount() == 2 ); + VERIFY( s.good() ); + VERIFY( s.get() == __gnu_cxx::char_traits<C>::eof() ); + VERIFY( s.eof() ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc index e5ec4e7..23d3a0a 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc @@ -16,11 +16,13 @@ // <http://www.gnu.org/licenses/>. // { dg-do run } +// { dg-options "-DSIMULATOR_TEST" { target simulator } } // PR libstdc++/94749 // basic_istream::ignore(n, c) discards n+1 if next character is equal to c. #include <sstream> +#include <limits> #include <testsuite_hooks.h> typedef wchar_t C; @@ -30,8 +32,10 @@ test01() { std::basic_istringstream<C> s(L" + -"); s.ignore(1, L'+'); + VERIFY( s.gcount() == 1 ); VERIFY( s.get() == L'+' ); s.ignore(3, L'-'); + VERIFY( s.gcount() == 3 ); VERIFY( s.get() == L'-' ); } @@ -40,8 +44,10 @@ test02() { std::basic_istringstream<C> s(L".+...-"); s.ignore(1, L'+'); + VERIFY( s.gcount() == 1 ); VERIFY( s.get() == L'+' ); s.ignore(3, L'-'); + VERIFY( s.gcount() == 3 ); VERIFY( s.get() == L'-' ); } @@ -50,8 +56,10 @@ test03() { std::basic_istringstream<C, __gnu_cxx::char_traits<C> > s(L" + -"); s.ignore(1, L'+'); + VERIFY( s.gcount() == 1 ); VERIFY( s.get() == L'+' ); s.ignore(3, L'-'); + VERIFY( s.gcount() == 3 ); VERIFY( s.get() == L'-' ); } @@ -60,17 +68,160 @@ test04() { std::basic_istringstream<C, __gnu_cxx::char_traits<C> > s(L".+...-"); s.ignore(1, L'+'); + VERIFY( s.gcount() == 1 ); VERIFY( s.get() == L'+' ); s.ignore(3, L'-'); + VERIFY( s.gcount() == 3 ); VERIFY( s.get() == L'-' ); } +// The original fix for PR libstdc++/94749 failed to discard the delimiter +// if it occurred after numeric_limits<streamsize>::max() had been seen. +// This streambuf will keep filling the get area with zero bytes until +// almost numeric_limits<streamsize>::max() characters have been read, +// and then return one more buffer that has L"123" at its end. +template<typename T> +struct buff : std::basic_streambuf<typename T::char_type, T> +{ + typedef typename T::char_type char_type; + typedef typename T::int_type int_type; + typedef std::streamsize streamsize; + typedef std::numeric_limits<streamsize> limits; + + buff() : count(0), buf() { } + + int_type underflow() + { + // Number of characters left until we overflow the counter + const streamsize headroom = limits::max() - count; + + if (headroom == 0) + return T::eof(); + + if (bufsz < headroom) + { + this->setg(buf, buf, buf + bufsz); + count += bufsz; + } + else + { + // write L"123" across the 2GB boundary + buf[headroom-1] = L'1'; + buf[headroom+0] = L'2'; + buf[headroom+1] = L'3'; + this->setg(buf, buf, buf + headroom + 2); + count = limits::max(); + } + + return buf[0]; + } + + streamsize count; + + static const streamsize bufsz = 2048 << limits::digits10; + char_type buf[bufsz + 2]; +}; + +void +test05() +{ + // Not possible to overflow 64-bit streamsize in reasonable time. + if (std::numeric_limits<std::streamsize>::digits > 32) + return; + + typedef std::char_traits<C> T; + + std::basic_istream<C, T> in(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), L'1'); + VERIFY(in.good()); + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == L'2'); + VERIFY(in.get() == L'3'); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), L'2'); + VERIFY(in.good()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == L'3'); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), L'3'); + VERIFY(in.good()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), L'4'); + VERIFY(in.eof()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(nullptr); +} + +void +test06() +{ + if (std::numeric_limits<std::streamsize>::digits > 32) + return; + + typedef __gnu_cxx::char_traits<C> T; + + std::basic_istream<C, T> in(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), L'1'); + VERIFY(in.good()); + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == L'2'); + VERIFY(in.get() == L'3'); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), L'2'); + VERIFY(in.good()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == L'3'); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), L'3'); + VERIFY(in.good()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(new buff<T>); + + in.ignore(std::numeric_limits<std::streamsize>::max(), L'4'); + VERIFY(in.eof()); + // The standard doesn't say what gcount() should return in this case: + VERIFY(in.gcount() == std::numeric_limits<std::streamsize>::max()); + VERIFY(in.get() == T::eof()); + + delete in.rdbuf(nullptr); +} int main() { - // test01(); - // test02(); + test01(); + test02(); test03(); test04(); + test05(); +#ifndef SIMULATOR_TEST + test06(); +#endif } diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/96161.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/96161.cc new file mode 100644 index 0000000..6423442 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/96161.cc @@ -0,0 +1,79 @@ +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run } + +// PR libstdc++/96161 +// basic_istream::ignore sets eofbit too soon + +#include <sstream> +#include <limits> +#include <testsuite_hooks.h> + +typedef wchar_t C; + +void +test01() +{ + std::basic_istringstream<C> s(L" "); + s.ignore(2, L'+'); + VERIFY( s.gcount() == 2 ); + VERIFY( s.good() ); + VERIFY( s.get() == std::char_traits<C>::eof() ); + VERIFY( s.eof() ); +} + +void +test02() +{ + std::basic_istringstream<C> s(L" "); + s.ignore(2); + VERIFY( s.gcount() == 2 ); + VERIFY( s.good() ); + VERIFY( s.get() == std::char_traits<C>::eof() ); + VERIFY( s.eof() ); +} + +void +test03() +{ + std::basic_istringstream<C, __gnu_cxx::char_traits<C> > s(L" "); + s.ignore(2, L'+'); + VERIFY( s.gcount() == 2 ); + VERIFY( s.good() ); + VERIFY( s.get() == __gnu_cxx::char_traits<C>::eof() ); + VERIFY( s.eof() ); +} + +void +test04() +{ + std::basic_istringstream<C, __gnu_cxx::char_traits<C> > s(L" "); + s.ignore(2); + VERIFY( s.gcount() == 2 ); + VERIFY( s.good() ); + VERIFY( s.get() == __gnu_cxx::char_traits<C>::eof() ); + VERIFY( s.eof() ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} |