1 // 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
2
3 // Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20
21 // 27.8.1.4 Overridden virtual functions
22
23 #include <fstream>
24 #include <unistd.h>
25 #include <signal.h>
26 #include <fcntl.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <locale>
30 #include <testsuite_hooks.h>
31
32 // @require@ %-*.tst %-*.txt
33 // @diff@ %-*.tst %*.txt
34
test01()35 void test01()
36 {
37 using namespace std;
38
39 bool test = true;
40 char buf[512];
41 const char* strlit = "how to tell a story and other essays: mark twain";
42 const size_t strlitsize = std::strlen(strlit);
43 filebuf fbuf01;
44
45 fbuf01.pubsetbuf(buf, 512);
46 fbuf01.sputn(strlit, strlitsize);
47 VERIFY( std::strncmp(strlit, buf, strlitsize) != 0 );
48 }
49
test02()50 void test02()
51 {
52 using namespace std;
53
54 bool test = true;
55 char buf[512];
56 const char* strlit = "how to tell a story and other essays: mark twain";
57 const size_t strlitsize = std::strlen(strlit);
58 filebuf fbuf01;
59 fbuf01.open("tmp", ios_base::out);
60
61 fbuf01.pubsetbuf(buf, strlitsize);
62 fbuf01.sputn(strlit, strlitsize);
63 VERIFY( std::strncmp(strlit, buf, strlitsize) == 0 );
64 }
65
66
67 // NB: This test assumes that _M_buf_size == 40, and not the usual
68 // buffer_size length of BUFSIZ (8192), so that overflow/underflow can be
69 // simulated a bit more readily.
70 // NRB (Nota Really Bene): setting it to 40 breaks the test, as intended.
71 const int buffer_size = 8192;
72 //const int buffer_size = 40;
73
74 const char carray_01[] = "santa cruz or sandiego?";
75 const char carray_02[] = "memphis, new orleans, and savanah";
76 const char name_01[] = "filebuf_virtuals-1.txt"; // file with data in it
77 const char name_02[] = "filebuf_virtuals-2.txt"; // empty file, need to create
78 const char name_03[] = "filebuf_virtuals-3.txt"; // empty file, need to create
79 const char name_04[] = "filebuf_virtuals-4.txt"; // empty file, need to create
80 const char name_05[] = "filebuf_virtuals-5.txt"; // empty file, need to create
81 const char name_06[] = "filebuf_virtuals-6.txt"; // empty file, need to create
82 const char name_07[] = "filebuf_virtuals-7.txt"; // empty file, need to create
83
84 class derived_filebuf: public std::filebuf
85 {
86 public:
87 void
set_size(int_type __size)88 set_size(int_type __size) { _M_buf_size_opt = __size; }
89 };
90
91 derived_filebuf fb_01; // in
92 derived_filebuf fb_02; // out
93 derived_filebuf fb_03; // in | out
94
95
96 // Initialize filebufs to be the same size regardless of platform.
test03()97 void test03()
98 {
99 fb_01.set_size(buffer_size);
100 fb_02.set_size(buffer_size);
101 fb_03.set_size(buffer_size);
102 }
103
104
105 // Test the filebuf/stringbuf locale settings.
test04()106 void test04()
107 {
108 std::locale loc_tmp;
109 loc_tmp = fb_01.getloc();
110 fb_01.pubimbue(loc_tmp); //This should initialize _M_init to true
111 fb_01.getloc(); //This should just return _M_locale
112 }
113
114 // Test overloaded virtual functions.
test05()115 void test05()
116 {
117 typedef std::filebuf::int_type int_type;
118 typedef std::filebuf::traits_type traits_type;
119 typedef std::filebuf::pos_type pos_type;
120 typedef std::filebuf::off_type off_type;
121 typedef size_t size_type;
122
123 bool test = true;
124 std::filebuf f_tmp;
125 std::streamsize strmsz_1, strmsz_2;
126 std::streamoff strmof_1, strmof_2;
127 int i = 0, j = 0, k = 0;
128
129 // GET
130 // int showmanyc()
131 // returns an estimate of the numbers of chars in the seq, or -1.
132 // if __retval > 0, then calls to underflow won't return
133 // traits_type::eof() till at least __retval chars.
134 // if __retval == -1, then calls to underflow or uflow will fail.
135 // NB overriding def if it can determine more chars can be read from
136 // the input sequence.
137
138 // int in_avail()
139 // if a read position is available, return _M_in_end - _M_in_cur.
140 // else return showmanyc.
141 strmof_1 = fb_01.in_avail();
142 strmof_2 = fb_02.in_avail();
143 VERIFY( strmof_1 == -1 );
144 VERIFY( strmof_1 == strmof_2 ); //fail because not open
145 strmof_1 = fb_03.in_avail();
146 VERIFY( strmof_1 == strmof_2 );
147 fb_01.open(name_01, std::ios_base::in);
148 fb_02.open(name_02, std::ios_base::out | std::ios_base::trunc);
149 fb_03.open(name_03, std::ios_base::out | std::ios_base::in | std::ios_base::trunc);
150 strmof_1 = fb_01.in_avail();
151 strmof_2 = fb_02.in_avail();
152 VERIFY( strmof_1 != strmof_2 );
153 VERIFY( strmof_1 >= 0 );
154 VERIFY( strmof_2 == -1 ); // empty file
155 strmof_1 = fb_03.in_avail();
156 VERIFY( strmof_1 == 0 ); // empty file
157
158 // int_type sbumpc()
159 // if read_cur not avail returns uflow(), else return *read_cur & increment
160 int_type c1 = fb_01.sbumpc();
161 int_type c2 = fb_02.sbumpc();
162 VERIFY( c1 != c2 );
163 VERIFY( c1 == '/' );
164 VERIFY( c2 == -1 );
165 int_type c3 = fb_01.sbumpc();
166 int_type c4 = fb_02.sbumpc();
167 VERIFY( c3 != c4 );
168 VERIFY( c1 == c3 ); // fluke, both happen to be '/'
169 VERIFY( c2 == c4 );
170 int_type c5 = fb_03.sbumpc();
171 VERIFY( c5 == traits_type::eof() );
172 // XXX should do some kind of test to make sure that internal
173 // buffers point ot the same thing, to check consistancy.
174
175 // int_type sgetc()
176 // if read_cur not avail, return uflow(), else return *read_cur
177 int_type c6 = fb_01.sgetc();
178 int_type c7 = fb_02.sgetc();
179 VERIFY( c6 != c3 );
180 VERIFY( c7 == c4 ); // both -1
181 int_type c8 = fb_01.sgetc();
182 int_type c9 = fb_02.sgetc();
183 VERIFY( c6 == c8 );
184 VERIFY( c7 == c9 );
185 c5 = fb_03.sgetc();
186 VERIFY( c5 == traits_type::eof() );
187
188 // int_type snextc()
189 // calls sbumpc and if sbumpc != eof, return sgetc
190 c6 = fb_01.snextc();
191 c7 = fb_02.snextc();
192 VERIFY( c6 != c8 );
193 VERIFY( c7 == c9 ); // -1
194 VERIFY( c6 == '9' );
195 c6 = fb_01.snextc();
196 c7 = fb_02.snextc();
197 VERIFY( c6 != c8 );
198 VERIFY( c7 == c9 ); // -1
199 VERIFY( c6 == '9' );
200 c5 = fb_03.snextc();
201 VERIFY( c5 == traits_type::eof() );
202
203 // streamsize sgetn(char_type *s, streamsize n)
204 // streamsize xsgetn(char_type *s, streamsize n)
205 // assign up to n chars to s from input sequence, indexing in_cur as
206 // approp and returning the number of chars assigned
207 strmsz_1 = fb_01.in_avail();
208 strmsz_2 = fb_02.in_avail();
209 test = strmsz_1 != strmsz_2;
210 char carray1[13] = "";
211 strmsz_1 = fb_01.sgetn(carray1, 10);
212 char carray2[buffer_size] = "";
213 strmsz_2 = fb_02.sgetn(carray2, 10);
214 VERIFY( strmsz_1 != strmsz_2 );
215 VERIFY( strmsz_1 == 10 );
216 VERIFY( strmsz_2 == 0 );
217 c1 = fb_01.sgetc();
218 c2 = fb_02.sgetc();
219 VERIFY( c1 == '\n' );
220 VERIFY( c7 == c2 ); // n != i
221 strmsz_1 = fb_03.sgetn(carray1, 10);
222 VERIFY( !strmsz_1 ); //zero
223 strmsz_1 = fb_01.in_avail();
224 strmsz_2 = fb_01.sgetn(carray2, strmsz_1 + 5);
225 VERIFY( strmsz_1 == strmsz_2 - 5 );
226 c4 = fb_01.sgetc(); // buffer should have underflowed from above.
227 VERIFY( c4 == 'i' );
228 strmsz_1 = fb_01.in_avail();
229 VERIFY( strmsz_1 > 0 );
230 strmsz_2 = fb_01.sgetn(carray2, strmsz_1 + 5);
231 VERIFY( strmsz_1 == strmsz_2 ); //at the end of the actual file
232 strmsz_1 = fb_02.in_avail();
233 strmsz_2 = fb_02.sgetn(carray2, strmsz_1 + 5);
234 VERIFY( strmsz_1 == -1 );
235 VERIFY( strmsz_2 == 0 );
236 c4 = fb_02.sgetc(); // should be EOF
237 VERIFY( c4 == traits_type::eof() );
238
239 // PUT
240 // int_type sputc(char_type c)
241 // if out_cur not avail, return overflow(traits_type::to_int_type(c))
242 // else, stores c at out_cur,
243 // increments out_cur, and returns c as int_type
244 // strmsz_1 = fb_03.in_avail(); // XXX valid for in|out??
245 c1 = fb_02.sputc('a');
246 c2 = fb_03.sputc('b');
247 VERIFY( c1 != c2 );
248 c1 = fb_02.sputc('c');
249 c2 = fb_03.sputc('d');
250 VERIFY( c1 != c2 );
251 // strmsz_2 = fb_03.in_avail();
252 // VERIFY( strmsz_1 != strmsz_2 );
253 for (int i = 50; i <= 90; ++i)
254 c2 = fb_02.sputc(char(i));
255 // 27filebuf-2.txt == ac23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX
256 // fb_02._M_out_cur = '2'
257 strmsz_1 = fb_03.in_avail();
258 for (int i = 50; i <= 90; ++i)
259 c2 = fb_03.sputc(char(i));
260 strmsz_2 = fb_03.in_avail();
261 // VERIFY( strmsz_1 != strmsz_2 );
262 // VERIFY( strmsz_1 > 0 );
263 // VERIFY( strmsz_2 > 0 );
264 // 27filebuf-2.txt == bd23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX
265 // fb_02._M_out_cur = '2'
266 c3 = fb_01.sputc('a'); // should be EOF because this is read-only
267 VERIFY( c3 == traits_type::eof() );
268
269 // streamsize sputn(const char_typs* s, streamsize n)
270 // write up to n chars to out_cur from s, returning number assigned
271 // NB *sputn will happily put '\0' into your stream if you give it a chance*
272 strmsz_1 = fb_03.sputn("racadabras", 10);//"abracadabras or what?"
273 VERIFY( strmsz_1 == 10 );
274 strmsz_2 = fb_03.sputn(", i wanna reach out and", 10);
275 VERIFY( strmsz_2 == 10 );
276 VERIFY( strmsz_1 == strmsz_2 );
277 // fb_03._M_out_beg = "YZracadabras, i wanna FGHIJKLMNOPQRSTUVW"
278 // fb_03._M_out_cur = "FGHIJKLMNOPQRSTUVW"
279 strmsz_1 = fb_02.sputn("racadabras", 10);
280 VERIFY( strmsz_1 == 10 );
281 // fb_02._M_out_beg = "YZracadabras<=>?@ABCDEFGHIJKLMNOPQRSTUVW"
282 // fb_02._M_out_cur = "<=>?@ABCDEFGHIJKLMNOPQRSTUVW"
283 strmsz_1 = fb_01.sputn("racadabra", 10);
284 VERIFY( strmsz_1 == 0 );
285
286 // PUTBACK
287 // int_type pbfail(int_type c)
288 // called when gptr() null, gptr() == eback(), or traits::eq(*gptr, c) false
289 // "pending sequence" is:
290 // 1) everything as defined in underflow
291 // 2) + if (traits::eq_int_type(c, traits::eof()), then input
292 // sequence is backed up one char before the pending sequence is
293 // determined.
294 // 3) + if (not 2) then c is prepended. Left unspecified is
295 // whether the input sequence is backedup or modified in any way
296 // returns traits::eof() for failure, unspecified other value for success
297
298 // int_type sputbackc(char_type c)
299 // if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
300 // otherwise decrements in_cur and returns *gptr()
301 c1 = fb_03.sgetc(); // -1
302 c2 = fb_03.sputbackc('z');
303 strmsz_2 = fb_03.in_avail();
304 c3 = fb_03.sgetc();
305 VERIFY( c3 == c2 );
306 VERIFY( c1 != c3 );
307 VERIFY( 1 == strmsz_2 );
308 //test for _in_cur == _in_beg
309 // fb_03._M_out_beg = "bd23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZracada" etc
310 fb_03.pubseekoff(10, std::ios_base::beg,
311 std::ios_base::in | std::ios_base::out);
312 fb_03.sputc('m');
313 strmsz_1 = fb_03.in_avail();
314 c1 = fb_03.sgetc();
315 fb_03.snextc();
316 c2 = fb_03.sputbackc('z');
317 strmsz_2 = fb_03.in_avail();
318 c3 = fb_03.sgetc();
319 VERIFY( c1 != c2 );
320 VERIFY( c3 == c2 );
321 VERIFY( c1 != c3 );
322 VERIFY( c2 == 'z' );
323 // VERIFY( strmsz_1 == strmsz_2 );
324 // test for replacing char with identical one
325 fb_03.snextc();
326 fb_03.sputc('u');
327 fb_03.sputc('v');
328 fb_03.sputc('a');
329 strmsz_1 = fb_03.in_avail();
330 c2 = fb_03.sputbackc('a');
331 strmsz_2 = fb_03.in_avail();
332 c3 = fb_03.sgetc();
333 VERIFY( c3 == c2 );
334 VERIFY( strmsz_1 + 1 == strmsz_2 );
335 //test for ios_base::out
336 c1 = fb_02.sgetc(); // undefined
337 c2 = fb_02.sputbackc('a');
338 VERIFY( c1 == c2 );
339 VERIFY( c1 == -1 );
340
341 // int_type sungetc()
342 // if in_cur not avail, return pbackfail(), else decrement and
343 // return to_int_type(*gptr())
344 // fb_03._M_out_beg = "uvaacadabras, i wannaZ[\\]^_`abcdefghijkl"
345 // fb_03._M_out_cur = "aacadabras, i wannaZ[\\]^_`abcdefghijkl"
346 strmsz_1 = fb_03.in_avail();
347 c2 = fb_03.sungetc(); // delete the 'a'
348 strmsz_2 = fb_03.in_avail();
349 VERIFY( c2 == 'v' ); // VERIFY( c2 != traits_type::eof() );
350 VERIFY( strmsz_1 + 1 == strmsz_2 );
351 //test for _in_cur == _in_beg
352 for (int i = 50; i < 32 + 29; ++i)
353 fb_02.sputc(char(i));
354 fb_02.pubseekoff(0, std::ios_base::beg, std::ios_base::out);
355 c1 = fb_02.sgetc();
356 strmsz_1 = fb_02.in_avail();
357 c2 = fb_02.sungetc();
358 c3 = fb_02.sgetc();
359 strmsz_2 = fb_02.in_avail();
360 VERIFY( c1 == c2 );
361 VERIFY( c2 == c3 );
362 VERIFY( c1 == traits_type::eof() );
363 VERIFY( strmsz_1 == strmsz_2 );
364 //test for _in_cur == _in_end
365 fb_03.pubseekoff(0, std::ios_base::end);
366 strmsz_1 = fb_03.in_avail(); // -1 cuz at the end
367 c1 = fb_03.sgetc();
368 c2 = fb_03.sungetc();
369 strmsz_2 = fb_03.in_avail(); // 1
370 c3 = fb_03.sgetc();
371 VERIFY( c1 != c2 );
372 // VERIFY( c2 == c3 || c2 == traits_type::not_eof(int(c3)) );
373 VERIFY( strmsz_2 != strmsz_1 );
374 VERIFY( strmsz_2 == 1 );
375 //test for ios_base::out
376
377 // BUFFER MANAGEMENT & POSITIONING
378 // int sync()
379 // if a put area exists, overflow.
380 // if a get area exists, do something undefined. (like, nothing)
381 strmsz_1 = fb_01.in_avail();
382 fb_01.pubsync();
383 strmsz_2 = fb_01.in_avail();
384 VERIFY( strmsz_2 == strmsz_1 );
385 strmsz_1 = fb_02.in_avail();
386 fb_02.pubsync();
387 // 27filebuf-2.txt == 53 bytes after this.
388 strmsz_2 = fb_02.in_avail();
389 VERIFY( strmsz_2 == -1 );
390 VERIFY( strmsz_2 == strmsz_1 );
391 strmsz_1 = fb_03.in_avail();
392 fb_03.pubsync();
393 // 27filebuf-3.txt
394 // bd23456789mzuva?@ABCDEFGHIJKLMNOPQRSTUVWXYZracadabras, i wannaz
395 // 63 bytes.
396 strmsz_2 = fb_03.in_avail();
397 VERIFY( strmsz_1 == 1 );
398 // VERIFY( strmsz_2 == 1 );
399
400 // setbuf
401 // pubsetbuf(char_type* s, streamsize n)
402 fb_01.pubsetbuf(0,0);
403 fb_02.pubsetbuf(0,0);
404 fb_03.pubsetbuf(0,0);
405 // Need to test unbuffered output, which means calling this on some
406 // things that have just been opened.
407
408
409 // seekoff
410 // pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which)
411 // alters the stream position to off
412 pos_type pt_1(off_type(-1));
413 pos_type pt_2(off_type(0));
414 off_type off_1 = 0;
415 off_type off_2 = 0;
416 //IN|OUT
417 // 27filebuf-3.txt = bd23456789:;<=>?...
418 //beg
419 strmsz_1 = fb_03.in_avail();
420 pt_1 = fb_03.pubseekoff(2, std::ios_base::beg);
421 strmsz_2 = fb_03.in_avail();
422 off_1 = pt_1;
423 VERIFY( off_1 > 0 );
424 c1 = fb_03.snextc(); //current in pointer +1
425 VERIFY( c1 == '3' );
426 c2 = fb_03.sputc('\n'); //current in pointer +1
427 c3 = fb_03.sgetc();
428 VERIFY( c2 != c3 );
429 VERIFY( c3 == '4' );
430 fb_03.pubsync();
431 c1 = fb_03.sgetc();
432 VERIFY( c1 == c3 );
433 //cur
434 // 27filebuf-3.txt = bd2\n456789:;<=>?...
435 pt_2 = fb_03.pubseekoff(2, std::ios_base::cur);
436 off_2 = pt_2;
437 VERIFY( (off_2 == (off_1 + 2 + 1 + 1)) );
438 c1 = fb_03.snextc(); //current in pointer +1
439 VERIFY( c1 == '7' );
440 c2 = fb_03.sputc('x'); //test current out pointer
441 c3 = fb_03.sputc('\n');
442 c1 = fb_03.sgetc();
443 fb_03.pubsync();
444 c3 = fb_03.sgetc();
445 VERIFY( c1 == c3 );
446 //end
447 // 27filebuf-3.txt = "bd2\n456x\n9"
448 pt_2 = fb_03.pubseekoff(0, std::ios_base::end,
449 std::ios_base::in|std::ios_base::out);
450 off_1 = pt_2;
451 VERIFY( off_1 > off_2 ); //weak, but don't know exactly where it ends
452 c3 = fb_03.sputc('\n');
453 strmsz_1 = fb_03.sputn("because because because. . .", 28);
454 VERIFY( strmsz_1 == 28 );
455 c1 = fb_03.sungetc();
456 // Defect? retval of sungetc is not necessarily the character ungotten.
457 // So re-get it.
458 c1 = fb_03.sgetc();
459 fb_03.pubsync();
460 c3 = fb_03.sgetc();
461 VERIFY( c1 == c3 );
462 // IN
463 // OUT
464
465
466 // seekpos
467 // pubseekpos(pos_type sp, ios_base::openmode)
468 // alters the stream position to sp
469 //IN|OUT
470 //beg
471 pt_1 = fb_03.pubseekoff(78, std::ios_base::beg);
472 off_1 = pt_1;
473 VERIFY( off_1 > 0 );
474 c1 = fb_03.snextc(); //current in pointer +1
475 VERIFY( c1 == ' ' );
476 c2 = fb_03.sputc('\n'); //test current out pointer
477 c3 = fb_03.sgetc();
478 fb_03.pubsync(); //resets pointers
479 pt_2 = fb_03.pubseekpos(pt_1);
480 off_2 = pt_2;
481 VERIFY( off_1 == off_2 );
482 c3 = fb_03.snextc(); //current in pointer +1
483 VERIFY( c2 == c3 );
484 pt_1 = fb_03.pubseekoff(0, std::ios_base::end);
485 off_1 = pt_1;
486 VERIFY( off_1 > off_2 );
487 fb_03.sputn("\nof the wonderful things he does!!\nok", 37);
488 fb_03.pubsync();
489
490 // IN
491 // OUT
492
493 // VIRTUALS (indirectly tested)
494 // underflow
495 // if read position avail, returns *gptr()
496
497 // pbackfail(int_type c)
498 // put c back into input sequence
499
500 // overflow
501 // appends c to output seq
502
503 // NB Have to close these suckers. . .
504 // filebuf_type* close()
505 fb_01.close();
506 fb_02.close();
507 fb_03.close();
508 VERIFY( !fb_01.is_open() );
509 VERIFY( !fb_02.is_open() );
510 VERIFY( !fb_03.is_open() );
511 }
512
test06()513 void test06()
514 {
515 using namespace std;
516 typedef istream::int_type int_type;
517
518 bool test = true;
519 ifstream ifs(name_02);
520 char buffer[] = "xxxxxxxxxx";
521 int_type len1 = ifs.rdbuf()->sgetn(buffer, sizeof(buffer));
522 VERIFY( len1 == sizeof(buffer) );
523 VERIFY( buffer[0] == 'a' );
524 }
525
526 // libstdc++/9322
test07()527 void test07()
528 {
529 using std::locale;
530 bool test = true;
531
532 locale loc;
533 std::filebuf ob;
534 VERIFY( ob.getloc() == loc );
535
536 locale::global(locale("en_US"));
537 VERIFY( ob.getloc() == loc );
538
539 locale loc_de ("de_DE");
540 locale ret = ob.pubimbue(loc_de);
541 VERIFY( ob.getloc() == loc_de );
542 VERIFY( ret == loc );
543
544 locale::global(loc);
545 VERIFY( ob.getloc() == loc_de );
546 }
547
548 class MyTraits : public std::char_traits<char>
549 {
550 public:
eq(char c1,char c2)551 static bool eq(char c1, char c2)
552 {
553 VERIFY( c1 != 'X' );
554 VERIFY( c2 != 'X' );
555 return std::char_traits<char>::eq(c1, c2);
556 }
557 };
558
559 class MyBuf : public std::basic_streambuf<char, MyTraits>
560 {
561 char buffer[8];
562
563 public:
MyBuf()564 MyBuf()
565 {
566 std::memset(buffer, 'X', sizeof(buffer));
567 std::memset(buffer + 2, 'f', 4);
568 setg(buffer + 2, buffer + 2, buffer + 6);
569 }
570 };
571
572 // libstdc++/9538
test08()573 void test08()
574 {
575 bool test = true;
576
577 MyBuf mb;
578 mb.sputbackc('a');
579 }
580
581 // libstdc++/9439, libstdc++/9425
test09()582 void test09()
583 {
584 using namespace std;
585 bool test = true;
586
587 filebuf fbuf;
588 fbuf.open(name_01, ios_base::in);
589 filebuf::int_type r = fbuf.sputbackc('a');
590 fbuf.close();
591
592 VERIFY( r == filebuf::traits_type::eof() );
593 }
594
595 class Cvt_to_upper : public std::codecvt<char, char, mbstate_t>
596 {
do_always_noconv() const597 bool do_always_noconv() const throw()
598 {
599 return false;
600 }
601 };
602
603 // libstdc++/9169
test10()604 void test10()
605 {
606 using namespace std;
607 bool test = true;
608
609 locale c_loc;
610 locale loc(c_loc, new Cvt_to_upper);
611
612 string str("abcdefghijklmnopqrstuvwxyz");
613 string tmp;
614
615 {
616 ofstream out;
617 out.imbue(loc);
618 out.open(name_04);
619 copy(str.begin(), str.end(),
620 ostreambuf_iterator<char>(out));
621 }
622
623 {
624 ifstream in;
625 in.open(name_04);
626 copy(istreambuf_iterator<char>(in),
627 istreambuf_iterator<char>(),
628 back_inserter(tmp));
629 }
630
631 VERIFY( tmp.size() == str.size() );
632 VERIFY( tmp == str );
633 }
634
635 // libstdc++/9825
test11()636 void test11()
637 {
638 using namespace std;
639 bool test = true;
640
641 filebuf fbuf;
642
643 fbuf.open(name_05, ios_base::in|ios_base::out|ios_base::trunc);
644 fbuf.sputn("crazy bees!", 11);
645 fbuf.pubseekoff(0, ios_base::beg);
646 fbuf.sbumpc();
647 fbuf.sputbackc('x');
648 filebuf::int_type c = fbuf.sbumpc();
649 VERIFY( c == 'x' );
650 c = fbuf.sbumpc();
651 VERIFY( c == 'r' );
652 c = fbuf.sbumpc();
653 VERIFY( c == 'a' );
654 fbuf.close();
655 }
656
657 class errorcvt : public std::codecvt<char, char, mbstate_t>
658 {
659 protected:
660 std::codecvt_base::result
do_out(mbstate_t &,const char * from,const char *,const char * & from_next,char * to,char *,char * & to_next) const661 do_out(mbstate_t&, const char* from, const char*,
662 const char*& from_next, char* to, char*,
663 char*& to_next) const
664 {
665 from_next = from;
666 to_next = to;
667 return std::codecvt<char, char, mbstate_t>::error;
668 }
669
do_always_noconv() const670 virtual bool do_always_noconv() const throw()
671 {
672 return false;
673 }
674 };
675
676 // libstdc++/9182
test12()677 void test12()
678 {
679 using namespace std;
680 bool test = true;
681
682 locale loc;
683 loc = locale(loc, new errorcvt);
684
685 filebuf fbuf1;
686 fbuf1.pubimbue(loc);
687 fbuf1.open(name_06, ios_base::out | ios_base::trunc);
688 fbuf1.sputn("ison", 4);
689 int r = fbuf1.pubsync();
690 VERIFY( r == -1 );
691 fbuf1.close();
692 }
693
test13()694 void test13()
695 {
696 using namespace std;
697 bool test = true;
698
699 locale loc;
700 loc = locale(loc, new errorcvt);
701
702 filebuf fbuf1;
703 fbuf1.pubimbue(loc);
704 fbuf1.pubsetbuf(0, 0);
705 fbuf1.open(name_06, ios_base::out | ios_base::trunc);
706 streamsize n = fbuf1.sputn("onne", 4);
707 VERIFY( n == 0 );
708 fbuf1.close();
709 }
710
711 class OverBuf : public std::filebuf
712 {
713 public:
pub_overflow(int_type c=traits_type::eof ())714 int_type pub_overflow(int_type c = traits_type::eof())
715 { return std::filebuf::overflow(c); }
716 };
717
718 // libstdc++/9988
test14()719 void test14()
720 {
721 using namespace std;
722 bool test = true;
723
724 OverBuf fb;
725 fb.open(name_07, ios_base::out | ios_base::trunc);
726
727 fb.sputc('a');
728 fb.pub_overflow('b');
729 fb.pub_overflow();
730 fb.sputc('c');
731 fb.close();
732
733 filebuf fbin;
734 fbin.open(name_07, ios_base::in);
735 filebuf::int_type c;
736 c = fbin.sbumpc();
737 VERIFY( c == 'a' );
738 c = fbin.sbumpc();
739 VERIFY( c == 'b' );
740 c = fbin.sbumpc();
741 VERIFY( c == 'c' );
742 c = fbin.sbumpc();
743 VERIFY( c == filebuf::traits_type::eof() );
744 fbin.close();
745 }
746
747 class UnderBuf : public std::filebuf
748 {
749 public:
750 int_type
pub_underflow()751 pub_underflow()
752 { return underflow(); }
753
754 std::streamsize
pub_showmanyc()755 pub_showmanyc()
756 { return showmanyc(); }
757 };
758
759 // libstdc++/10097
test15()760 void test15()
761 {
762 using namespace std;
763 bool test = true;
764
765 const char* name = "tmp_fifo1";
766
767 signal(SIGPIPE, SIG_IGN);
768 unlink(name);
769
770 if (0 != mkfifo(name, S_IRWXU))
771 {
772 VERIFY( false );
773 }
774
775 int fval = fork();
776 if (fval == -1)
777 {
778 unlink(name);
779 VERIFY( false );
780 }
781 else if (fval == 0)
782 {
783 filebuf fbout;
784 fbout.open(name, ios_base::out);
785 fbout.sputn("0123456789", 10);
786 fbout.pubsync();
787 sleep(2);
788 fbout.close();
789 exit(0);
790 }
791
792 UnderBuf fb;
793 fb.open(name, ios_base::in);
794 sleep(1);
795
796 fb.sgetc();
797 streamsize n = fb.pub_showmanyc();
798
799 while (n > 0)
800 {
801 --n;
802
803 UnderBuf::int_type c = fb.pub_underflow();
804 VERIFY( c != UnderBuf::traits_type::eof() );
805
806 fb.sbumpc();
807 }
808
809 fb.close();
810 }
811
main()812 main()
813 {
814 test01();
815 test02();
816
817 test03();
818 test04();
819 test05();
820 test06();
821
822 test07();
823 test08();
824 test09();
825 test10();
826 test11();
827 test12();
828 test13();
829 test14();
830 test15();
831 return 0;
832 }
833