32b604d5b15a2812e7bda9a0f2474af0eaff9678
1 // Copyright (C) 2020 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
19 // { dg-options "-DSIMULATOR_TEST" { target simulator } }
22 // basic_istream::ignore(n, c) discards n+1 if next character is equal to c.
26 #include <testsuite_hooks.h>
33 std::basic_istringstream
<C
> s(" + -");
35 VERIFY( s
.gcount() == 1 );
36 VERIFY( s
.get() == '+' );
38 VERIFY( s
.gcount() == 3 );
39 VERIFY( s
.get() == '-' );
45 std::basic_istringstream
<C
> s(".+...-");
47 VERIFY( s
.gcount() == 1 );
48 VERIFY( s
.get() == '+' );
50 VERIFY( s
.gcount() == 3 );
51 VERIFY( s
.get() == '-' );
57 std::basic_istringstream
<C
, __gnu_cxx::char_traits
<C
> > s(" + -");
59 VERIFY( s
.gcount() == 1 );
60 VERIFY( s
.get() == '+' );
62 VERIFY( s
.gcount() == 3 );
63 VERIFY( s
.get() == '-' );
69 std::basic_istringstream
<C
, __gnu_cxx::char_traits
<C
> > s(".+...-");
71 VERIFY( s
.gcount() == 1 );
72 VERIFY( s
.get() == '+' );
74 VERIFY( s
.gcount() == 3 );
75 VERIFY( s
.get() == '-' );
78 // The original fix for PR libstdc++/94749 failed to discard the delimiter
79 // if it occurred after numeric_limits<streamsize>::max() had been seen.
80 // This streambuf will keep filling the get area with zero bytes until
81 // almost numeric_limits<streamsize>::max() characters have been read,
82 // and then return one more buffer that has "123" at its end.
84 struct buff
: std::basic_streambuf
<typename
T::char_type
, T
>
86 typedef typename
T::char_type char_type
;
87 typedef typename
T::int_type int_type
;
88 typedef std::streamsize streamsize
;
89 typedef std::numeric_limits
<streamsize
> limits
;
91 buff() : count(0), buf() { }
95 // Number of characters left until we overflow the counter
96 const streamsize headroom
= limits::max() - count
;
101 if (bufsz
< headroom
)
103 this->setg(buf
, buf
, buf
+ bufsz
);
108 // write "123" across the 2GB boundary
109 buf
[headroom
-1] = '1';
110 buf
[headroom
+0] = '2';
111 buf
[headroom
+1] = '3';
112 this->setg(buf
, buf
, buf
+ headroom
+ 2);
113 count
= limits::max();
121 static const streamsize bufsz
= 2048 << limits::digits10
;
122 char_type buf
[bufsz
+ 2];
128 // Not possible to overflow 64-bit streamsize in reasonable time.
129 if (std::numeric_limits
<std::streamsize
>::digits
> 32)
132 typedef std::char_traits
<C
> T
;
134 std::basic_istream
<C
, T
> in(new buff
<T
>);
136 in
.ignore(std::numeric_limits
<std::streamsize
>::max(), '1');
138 VERIFY(in
.gcount() == std::numeric_limits
<std::streamsize
>::max());
139 VERIFY(in
.get() == '2');
140 VERIFY(in
.get() == '3');
141 VERIFY(in
.get() == T::eof());
143 delete in
.rdbuf(new buff
<T
>);
145 in
.ignore(std::numeric_limits
<std::streamsize
>::max(), '2');
147 // The standard doesn't say what gcount() should return in this case:
148 VERIFY(in
.gcount() == std::numeric_limits
<std::streamsize
>::max());
149 VERIFY(in
.get() == '3');
150 VERIFY(in
.get() == T::eof());
152 delete in
.rdbuf(new buff
<T
>);
154 in
.ignore(std::numeric_limits
<std::streamsize
>::max(), '3');
156 // The standard doesn't say what gcount() should return in this case:
157 VERIFY(in
.gcount() == std::numeric_limits
<std::streamsize
>::max());
158 VERIFY(in
.get() == T::eof());
160 delete in
.rdbuf(new buff
<T
>);
162 in
.ignore(std::numeric_limits
<std::streamsize
>::max(), '4');
164 // The standard doesn't say what gcount() should return in this case:
165 VERIFY(in
.gcount() == std::numeric_limits
<std::streamsize
>::max());
166 VERIFY(in
.get() == T::eof());
168 delete in
.rdbuf(nullptr);
174 if (std::numeric_limits
<std::streamsize
>::digits
> 32)
177 typedef __gnu_cxx::char_traits
<C
> T
;
179 std::basic_istream
<C
, T
> in(new buff
<T
>);
181 in
.ignore(std::numeric_limits
<std::streamsize
>::max(), '1');
183 VERIFY(in
.gcount() == std::numeric_limits
<std::streamsize
>::max());
184 VERIFY(in
.get() == '2');
185 VERIFY(in
.get() == '3');
186 VERIFY(in
.get() == T::eof());
188 delete in
.rdbuf(new buff
<T
>);
190 in
.ignore(std::numeric_limits
<std::streamsize
>::max(), '2');
192 // The standard doesn't say what gcount() should return in this case:
193 VERIFY(in
.gcount() == std::numeric_limits
<std::streamsize
>::max());
194 VERIFY(in
.get() == '3');
195 VERIFY(in
.get() == T::eof());
197 delete in
.rdbuf(new buff
<T
>);
199 in
.ignore(std::numeric_limits
<std::streamsize
>::max(), '3');
201 // The standard doesn't say what gcount() should return in this case:
202 VERIFY(in
.gcount() == std::numeric_limits
<std::streamsize
>::max());
203 VERIFY(in
.get() == T::eof());
205 delete in
.rdbuf(new buff
<T
>);
207 in
.ignore(std::numeric_limits
<std::streamsize
>::max(), '4');
209 // The standard doesn't say what gcount() should return in this case:
210 VERIFY(in
.gcount() == std::numeric_limits
<std::streamsize
>::max());
211 VERIFY(in
.get() == T::eof());
213 delete in
.rdbuf(nullptr);
224 #ifndef SIMULATOR_TEST