From 13187a454dca9455422877ab1db31e92882c18f5 Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Tue, 16 Jan 2001 07:55:26 +0000 Subject: [PATCH] C++STYLE (classname): Add more existing and stylish patterns. 2001-01-16 Benjamin Kosnik * docs/html/17_intro/C++STYLE (classname): Add more existing and stylish patterns. libstdc++/944 * include/bits/istream.tcc (istream::sentry::sentry()): Set failbit if the state of the stream is not good. * testsuite/27_io/istream_sentry.cc (test02): Add test. * testsuite/27_io/istream_manip.cc (test01): Modify. libstdc++/1019 reported by Paolo Carlini * include/bits/istream.tcc (operator>>(istream&, string&)): Fix. * testsuite/21_strings/inserters_extractors.cc (test08): Add test. libstdc++/1057 * include/bits/std_streambuf.h (setp): Set _M_buf_size correctly. * include/bits/streambuf.tcc (xsputn): Remove outside if clause. (xsgetn): Same. Simplify. * testsuite/27_io/streambuf.cc (test04): Add testcases. reported by Larry Evans * include/bits/streambuf.tcc (streambuf::xsputn): Just check for equality with eof on returned value from overflow. From-SVN: r39059 --- libstdc++-v3/ChangeLog | 26 ++++ libstdc++-v3/docs/html/17_intro/C++STYLE | 59 ++++++--- libstdc++-v3/include/bits/fstream.tcc | 81 ++++++------ libstdc++-v3/include/bits/istream.tcc | 13 +- libstdc++-v3/include/bits/std_streambuf.h | 51 +++++--- libstdc++-v3/include/bits/streambuf.tcc | 120 +++++++----------- .../21_strings/inserters_extractors.cc | 21 ++- libstdc++-v3/testsuite/27_io/istream_manip.cc | 4 +- .../testsuite/27_io/istream_sentry.cc | 30 +++-- .../testsuite/27_io/istream_unformatted.cc | 4 +- libstdc++-v3/testsuite/27_io/streambuf.cc | 97 +++++++++++++- 11 files changed, 344 insertions(+), 162 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1f7822bd526..dc0461fcbd4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,29 @@ +2001-01-16 Benjamin Kosnik + + * docs/html/17_intro/C++STYLE (classname): Add more existing + and stylish patterns. + + libstdc++/944 + * include/bits/istream.tcc (istream::sentry::sentry()): Set + failbit if the tate of the stream is not good. + * testsuite/27_io/istream_sentry.cc (test02): Add test. + * testsuite/27_io/istream_manip.cc (test01): Modify. + + libstdc++/1019 + reported by Paolo Carlini + * include/bits/istream.tcc (operator>>(istream&, string&)): Fix. + * testsuite/21_strings/inserters_extractors.cc (test08): Add test. + + libstdc++/1057 + * include/bits/std_streambuf.h (setp): Set _M_buf_size correctly. + * include/bits/streambuf.tcc (xsputn): Remove outside if clause. + (xsgetn): Same. Simplify. + * testsuite/27_io/streambuf.cc (test04): Add testcases. + + reported by Larry Evans + * include/bits/streambuf.tcc (streambuf::xsputn): Just check for + equality with eof on returned value from overflow. + 2001-01-14 Andreas Jaeger * libio/libio.h: Add test for glibc 2.0. diff --git a/libstdc++-v3/docs/html/17_intro/C++STYLE b/libstdc++-v3/docs/html/17_intro/C++STYLE index 6a85ac6e2cb..5c010ed276e 100644 --- a/libstdc++-v3/docs/html/17_intro/C++STYLE +++ b/libstdc++-v3/docs/html/17_intro/C++STYLE @@ -1,5 +1,5 @@ -C++ Standard Library Style Guidelines DRAFT 1999-02-26 +C++ Standard Library Style Guidelines DRAFT 2001-01-15 ------------------------------------- This library is written to appropriate C++ coding standards. As such, @@ -99,8 +99,8 @@ Notable areas of divergence from what may be previous local practice 07. Member initialization lists All one line, separate from class name. - gribble::gribble() - : _M_private_data(0), _M_more_stuff(0), _M_helper(0); + gribble::gribble() : + _M_private_data(0), _M_more_stuff(0), _M_helper(0); { } -NOT- gribble::gribble() : _M_private_data(0), _M_more_stuff(0), _M_helper(0); @@ -148,15 +148,42 @@ Notable areas of divergence from what may be previous local practice Reason: Koenig lookup. -11. constructor member intialization lists +11. Namespaces + namespace std + { + blah blah blah; + } // namespace std + + -NOT- + + namespace std { + blah blah blah; + } // namespace std + +12. Spacing under protected and private in class declarations: + space above, none below + ie + + public: + int foo; + + -NOT- + public: + + int foo; + +13. Spacing WRT return statements. + no extra spacing before returns + ie + + } + return __ret; + + -NOT- + } + + return __ret; - should look like this: - ctype::ctype(const mask* __table, bool __del, size_t __refs) : - __ctype_abstract_base(__refs), _M_del(__table != 0 && __del), - _M_toupper(__ctype_toupper), _M_tolower(__ctype_tolower), - _M_ctable(static_cast(__ctype_b), - _M_table(__table == 0 ? _M_ctable : __table) - { } The library currently has a mixture of GNU-C and modern C++ coding @@ -264,8 +291,8 @@ namespace std extern long long _G_global_with_a_good_long_name; // avoid globals! # endif - // avoid in-class inline definitions, define separately; - // likewise for member class definitions: + // Avoid in-class inline definitions, define separately; + // likewise for member class definitions: inline int gribble::public_member() const { int __local = 0; return __local; } @@ -285,8 +312,8 @@ namespace std #endif /* _HEADER_ */ -namespace std { - +namespace std +{ template // notice: "typename", not "class", no space long_return_value_type function_name(char* pointer, // "char *pointer" is wrong. @@ -321,8 +348,8 @@ namespace std { { // doesn't fit in one line. } +} // namespace std -} diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index e43e8a328e7..f1ffda23eee 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -41,39 +41,44 @@ namespace std basic_filebuf<_CharT, _Traits>:: _M_filebuf_init() { - _M_buf_unified = true; // Tie input to output for basic_filebuf. - _M_buf_size = _M_buf_size_opt; - try { - _M_file = new __file_type(&_M_lock); - } - catch(...) { - delete _M_file; - throw; - } - } + if (!_M_file) + { + _M_buf_unified = true; // Tie input to output for basic_filebuf. + try + { _M_file = new __file_type(&_M_lock); } + catch(...) + { + delete _M_file; + throw; + } + } + } template void basic_filebuf<_CharT, _Traits>:: _M_allocate_buffers() { - // Allocate internal buffer. - try { - _M_buf = new char_type[_M_buf_size]; - } - catch(...) { - delete [] _M_buf; - throw; - } - - // Allocate pback buffer. - try { - _M_pback = new char_type[_M_pback_size]; - } - catch(...) { - delete [] _M_pback; - throw; - } + if (!_M_buf) + { + _M_buf_size = _M_buf_size_opt; + // Allocate internal buffer. + try { _M_buf = new char_type[_M_buf_size]; } + catch(...) + { + delete [] _M_buf; + throw; + } + + // Allocate pback buffer. + try + { _M_pback = new char_type[_M_pback_size]; } + catch(...) + { + delete [] _M_pback; + throw; + } + } } template @@ -86,13 +91,13 @@ namespace std template basic_filebuf<_CharT, _Traits>:: basic_filebuf(int __fd, const char* /*__name*/, ios_base::openmode __mode) - : __streambuf_type(), _M_state_cur(__state_type()), + : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()), _M_state_beg(__state_type()), _M_last_overflowed(false) { _M_fcvt = &use_facet<__codecvt_type>(this->getloc()); _M_filebuf_init(); _M_file->sys_open(__fd, __mode); - if (this->is_open() && _M_buf_size) + if (this->is_open()) { _M_allocate_buffers(); _M_mode = __mode; @@ -116,7 +121,7 @@ namespace std { _M_filebuf_init(); _M_file->open(__s, __mode); - if (this->is_open() && _M_buf_size) + if (this->is_open()) { _M_allocate_buffers(); _M_mode = __mode; @@ -157,13 +162,15 @@ namespace std #endif _M_mode = ios_base::openmode(0); - if (_M_buf_size) - delete [] _M_buf; - _M_buf = NULL; - delete [] _M_pback; - _M_pback = NULL; - this->setg(NULL, NULL, NULL); - this->setp(NULL, NULL); + if (_M_buf) + { + delete [] _M_buf; + _M_buf = NULL; + delete [] _M_pback; + _M_pback = NULL; + this->setg(NULL, NULL, NULL); + this->setp(NULL, NULL); + } __ret = this; } diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc index 0e32781439a..c25790708ac 100644 --- a/libstdc++-v3/include/bits/istream.tcc +++ b/libstdc++-v3/include/bits/istream.tcc @@ -1,4 +1,4 @@ -// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2001 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 @@ -66,7 +66,14 @@ namespace std { #endif } } - _M_ok = __in.good(); + + if (__in.good()) + _M_ok = true; + else + { + _M_ok = false; + __in.setstate(ios_base::failbit); + } } template @@ -1123,7 +1130,7 @@ namespace std { bool __testsp = __ctype->is(ctype_base::space, __c); bool __testeof = __c == __eof; - while (__extracted <= __n && !__testeof && !__testsp) + while (__extracted < __n && !__testeof && !__testsp) { __str += _Traits::to_char_type(__c); ++__extracted; diff --git a/libstdc++-v3/include/bits/std_streambuf.h b/libstdc++-v3/include/bits/std_streambuf.h index f4d65aeaae6..5cf7b023f4c 100644 --- a/libstdc++-v3/include/bits/std_streambuf.h +++ b/libstdc++-v3/include/bits/std_streambuf.h @@ -1,6 +1,6 @@ // Stream buffer classes -*- C++ -*- -// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2001 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 @@ -44,7 +44,7 @@ namespace std { template static streamsize - _S_copy_streambufs(basic_ios<_CharT, _Traits>& __ios, + _S_copy_streambufs(basic_ios<_CharT, _Traits>& _ios, basic_streambuf<_CharT, _Traits>* __sbin, basic_streambuf<_CharT, _Traits>* __sbout); @@ -83,7 +83,7 @@ namespace std { // leave it NULL. char_type* _M_buf; - // Actual size of internal buffer, in bytes. + // Actual size of allocated internal buffer, in bytes. int_type _M_buf_size; // Optimal or preferred size of internal buffer, in bytes. @@ -172,6 +172,17 @@ namespace std { } } + // Correctly sets the _M_in_cur pointer, and bumps the + // _M_out_cur pointer as well if necessary. + void + _M_in_cur_move(off_type __n) // argument needs to be +- + { + bool __testout = _M_out_cur; + _M_in_cur += __n; + if (__testout && _M_buf_unified) + _M_out_cur += __n; + } + // Correctly sets the _M_out_cur pointer, and bumps the // appropriate _M_*_end pointers as well. Necessary for the // un-tied stringbufs, in in|out mode. @@ -183,7 +194,7 @@ namespace std { void _M_out_cur_move(off_type __n) // argument needs to be +- { - bool __testin = _M_mode & ios_base::in; + bool __testin = _M_in_cur; _M_out_cur += __n; if (__testin && _M_buf_unified) @@ -197,6 +208,25 @@ namespace std { } } + // Return the size of the output buffer. This depends on the + // buffer in use: allocated buffers have a stored size in + // _M_buf_size and setbuf() buffers don't. + off_type + _M_out_buf_size() + { + off_type __ret = 0; + if (_M_out_cur) + { + // Using allocated buffer. + if (_M_out_beg == _M_buf) + __ret = _M_out_beg + _M_buf_size - _M_out_cur; + // Using non-allocated buffer. + else + __ret = _M_out_end - _M_out_cur; + } + return __ret; + } + // These three functions are used to clarify internal buffer // maintenance. After an overflow, or after a seekoff call that // started at beg or end, or possibly when the stream becomes @@ -219,11 +249,7 @@ namespace std { bool __testin = _M_mode & ios_base::in; bool __testout = _M_mode & ios_base::out; if (__testin) - { - this->setg(_M_buf, _M_buf, _M_buf + __off); - if (!__testout) - _M_buf_size = static_cast(__off); - } + this->setg(_M_buf, _M_buf, _M_buf + __off); if (__testout) this->setp(_M_buf, _M_buf + __off); @@ -404,12 +430,6 @@ namespace std { _M_out_end = __pend; if (!(_M_mode & ios_base::out) && __pbeg && __pend) _M_mode = _M_mode | ios_base::out; - // The output sequence is highly tied to _M_buf and - // _M_buf_size in addition to the actual pointers into the - // buffer. Because of this, (re)set _M_buf_size here, as - // sputc/xsputn need _M_buf_size to be accurate. (The - // corresponding input functions rely instead on _M_in_end.) - _M_buf_size = max(_M_buf_size, static_cast(__pend - __pbeg)); } // Virtual functions: @@ -460,7 +480,6 @@ namespace std { int_type __ret = traits_type::eof(); bool __testeof = this->underflow() == __ret; bool __testpending = _M_in_cur && _M_in_cur < _M_in_end; - if (!__testeof && __testpending) { __ret = traits_type::to_int_type(*_M_in_cur); diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc index d03b7bca104..8424e4610ab 100644 --- a/libstdc++-v3/include/bits/streambuf.tcc +++ b/libstdc++-v3/include/bits/streambuf.tcc @@ -1,6 +1,6 @@ // Stream buffer classes -*- C++ -*- -// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2001 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 @@ -45,9 +45,7 @@ namespace std { if (_M_in_cur && _M_in_cur < _M_in_end) { char_type __c = *gptr(); - ++_M_in_cur; - if (_M_buf_unified && _M_mode & ios_base::out) - ++_M_out_cur; + _M_in_cur_move(1); __ret = traits_type::to_int_type(__c); } else @@ -67,9 +65,7 @@ namespace std { __ret = pbackfail(traits_type::to_int_type(__c)); else { - --_M_in_cur; - if (_M_buf_unified && _M_mode & ios_base::out) - --_M_out_cur; + _M_in_cur_move(-1); __ret = traits_type::to_int_type(*this->gptr()); } return __ret; @@ -83,9 +79,7 @@ namespace std { int_type __ret; if (_M_in_cur && _M_in_beg < _M_in_cur) { - --_M_in_cur; - if (_M_buf_unified && _M_mode & ios_base::out) - --_M_out_cur; + _M_in_cur_move(-1); __ret = traits_type::to_int_type(*_M_in_cur); } else @@ -104,8 +98,7 @@ namespace std { sputc(char_type __c) { int_type __ret; - - if (_M_out_cur && _M_out_cur < _M_out_beg + _M_buf_size) + if (_M_out_buf_size()) { *_M_out_cur = __c; _M_out_cur_move(1); @@ -121,37 +114,27 @@ namespace std { basic_streambuf<_CharT, _Traits>:: xsgetn(char_type* __s, streamsize __n) { - bool __testout = _M_mode & ios_base::out; streamsize __ret = 0; - - if (__n) + while (__ret < __n) { - while (__ret < __n) + size_t __buf_len = _M_in_end - _M_in_cur; + if (__buf_len > 0) { - if (_M_in_cur < _M_in_end) - { - size_t __len; - if (_M_in_cur + __n - __ret <= _M_in_end) - __len = __n - __ret; - else - __len = _M_in_end - _M_in_cur; - traits_type::copy(__s, _M_in_cur, __len); - __ret += __len; - __s += __len; - _M_in_cur += __len; - if (_M_buf_unified && __testout) - _M_out_cur += __len; - } - - if (__ret != __n) - { - int_type __c = this->uflow(); - if (traits_type::eq_int_type(__c, traits_type::eof())) - break; - - traits_type::assign(*__s++, traits_type::to_char_type(__c)); - ++__ret; - } + size_t __remaining = __n - __ret; + size_t __len = min(__buf_len, __remaining); + traits_type::copy(__s, _M_in_cur, __len); + __ret += __len; + __s += __len; + _M_in_cur_move(__len); + } + + if (__ret < __n) + { + int_type __c = this->uflow(); + if (traits_type::eq_int_type(__c, traits_type::eof())) + break; + traits_type::assign(*__s++, traits_type::to_char_type(__c)); + ++__ret; } } return __ret; @@ -168,44 +151,32 @@ namespace std { xsputn(const char_type* __s, streamsize __n) { streamsize __ret = 0; - - if (__n) + while (__ret < __n) { - while (__ret < __n) + off_type __buf_len = _M_out_buf_size(); + if (__buf_len > 0) { - bool __testput = _M_out_cur < _M_out_beg + _M_buf_size; - bool __testout = _M_mode & ios_base::out; - if (!(__testput && __testout)) - { - int_type __c = traits_type::to_int_type(*__s); - int_type __overfc = this->overflow(__c); - if (traits_type::eq_int_type(__c, __overfc)) - { - ++__ret; - ++__s; - } - else - break; - } - - if (__ret != __n) - { - size_t __len; - if (_M_out_cur + __n - __ret <= _M_out_beg + _M_buf_size) - __len = __n - __ret; - else - __len = _M_out_beg + _M_buf_size - _M_out_cur; - traits_type::copy(_M_out_cur, __s, __len); - __ret += __len; - __s += __len; - _M_out_cur_move(__len); - } + off_type __remaining = __n - __ret; + off_type __len = min(__buf_len, __remaining); + traits_type::copy(_M_out_cur, __s, __len); + __ret += __len; + __s += __len; + _M_out_cur_move(__len); + } + + if (__ret < __n) + { + int_type __c = traits_type::to_int_type(*__s); + int_type __overfc = this->overflow(__c); + if (traits_type::eq_int_type(__overfc, traits_type::eof())) + break; + ++__ret; + ++__s; } } return __ret; } - // Conceivably, this could be used to implement buffer-to-buffer // copies, if this was ever desired in an un-ambiguous way by the // standard. If so, then checks for __ios being zero would be @@ -221,16 +192,13 @@ namespace std { streamsize __ret = 0; streamsize __bufsize = __sbin->in_avail(); streamsize __xtrct; - bool __testout = __sbin->_M_mode & ios_base::out; bool __testput = __sbout->_M_mode & ios_base::out; try { while (__testput && __bufsize != -1) { __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize); __ret += __xtrct; - __sbin->_M_in_cur += __xtrct; - if (__testout && __sbin->_M_buf_unified) - __sbin->_M_out_cur += __xtrct; + __sbin->_M_in_cur_move(__xtrct); if (__xtrct == __bufsize) { int_type __c = __sbin->sgetc(); @@ -251,7 +219,6 @@ namespace std { } return __ret; } - } // namespace std #endif // _CPP_BITS_STREAMBUF_TCC @@ -259,3 +226,4 @@ namespace std { + diff --git a/libstdc++-v3/testsuite/21_strings/inserters_extractors.cc b/libstdc++-v3/testsuite/21_strings/inserters_extractors.cc index 6ba5bdac284..733278288a1 100644 --- a/libstdc++-v3/testsuite/21_strings/inserters_extractors.cc +++ b/libstdc++-v3/testsuite/21_strings/inserters_extractors.cc @@ -1,6 +1,6 @@ // 1999-07-01 bkoz -// Copyright (C) 1999, 2000 Free Software Foundation, Inc. +// Copyright (C) 1999, 2000, 2001 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 @@ -29,6 +29,7 @@ #include #include #include +#include #include bool test01(void) @@ -287,6 +288,23 @@ void test07(void) #endif } +// libstdc++/1019 +void test08() +{ + using namespace std; + + bool test = true; + istringstream istrm("enero:2001"); + int year; + char sep; + string month; + + istrm >> setw(5) >> month >> sep >> year; + VERIFY( month.size() == 5 ); + VERIFY( sep == ':' ); + VERIFY( year == 2001 ); +} + int main() { test01(); @@ -302,6 +320,7 @@ int main() test06(); test07(); + test08(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/istream_manip.cc b/libstdc++-v3/testsuite/27_io/istream_manip.cc index 57d376cf0be..ba3826c79bb 100644 --- a/libstdc++-v3/testsuite/27_io/istream_manip.cc +++ b/libstdc++-v3/testsuite/27_io/istream_manip.cc @@ -1,6 +1,6 @@ // 1999-07-22 bkoz -// Copyright (C) 1994, 1999 Free Software Foundation, Inc. +// Copyright (C) 1994, 1999, 2001 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 @@ -70,7 +70,7 @@ bool test01(void) VERIFY( !iss02.eof() ); iss01 >> std::ws; - VERIFY( !iss01.fail() ); + VERIFY( iss01.fail() ); VERIFY( iss01.eof() ); #ifdef DEBUG_ASSERT diff --git a/libstdc++-v3/testsuite/27_io/istream_sentry.cc b/libstdc++-v3/testsuite/27_io/istream_sentry.cc index 5baca934fd7..cf4a1bb8099 100644 --- a/libstdc++-v3/testsuite/27_io/istream_sentry.cc +++ b/libstdc++-v3/testsuite/27_io/istream_sentry.cc @@ -1,6 +1,6 @@ // 1999-10-14 bkoz -// Copyright (C) 1999 Free Software Foundation, Inc. +// Copyright (C) 1999, 2001 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 @@ -57,16 +57,30 @@ void test01() std::istream::sentry sentry04(istr02, true); VERIFY( bool(sentry04) == true ); - -#ifdef DEBUG_ASSERT - assert(test); -#endif } - -int main() { - +// libstdc++/944 +void +test02() +{ + using namespace std; + istringstream in("80.21 56.89 12.3"); + bool test = true; + int i = 0; + double x; + + // ios_base::eof == 2 + while(in >> x) + { + ++i; + } + VERIFY( i == 3 ); +} + +int main() +{ test01(); + test02(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/istream_unformatted.cc b/libstdc++-v3/testsuite/27_io/istream_unformatted.cc index 3e479f2a629..76464d73ffa 100644 --- a/libstdc++-v3/testsuite/27_io/istream_unformatted.cc +++ b/libstdc++-v3/testsuite/27_io/istream_unformatted.cc @@ -1,6 +1,6 @@ // 1999-08-11 bkoz -// Copyright (C) 1999, 2000 Free Software Foundation +// Copyright (C) 1999, 2000, 2001 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 @@ -103,7 +103,7 @@ test01() VERIFY( is_04.peek() == traits_type::eof() ); VERIFY( is_04.gcount() == 0 ); state2 = is_04.rdstate(); - VERIFY( state1 == state2 ); + VERIFY( state1 != state2 ); // istream& putback(char c) diff --git a/libstdc++-v3/testsuite/27_io/streambuf.cc b/libstdc++-v3/testsuite/27_io/streambuf.cc index 8b289889314..4aaa8958408 100644 --- a/libstdc++-v3/testsuite/27_io/streambuf.cc +++ b/libstdc++-v3/testsuite/27_io/streambuf.cc @@ -1,6 +1,6 @@ // 1999-10-11 bkoz -// Copyright (C) 1999, 2000 Free Software Foundation, Inc. +// Copyright (C) 1999, 2000, 2001 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 @@ -31,6 +31,7 @@ #include // for memset, memcmp #include +#include #include #include @@ -232,6 +233,98 @@ void test03() #endif } +class setpbuf : public std::streambuf +{ + char buffer[4]; + std::string result; + +public: + + std::string& + get_result() + { return result; } + + setpbuf() + { + char foo [32]; + setp(foo, foo + 32); + setp(buffer, buffer + 4); + } + + ~setpbuf() + { sync(); } + + virtual int_type + overflow(int_type n) + { + if (sync() != 0) + return traits_type::eof(); + + result += traits_type::to_char_type(n); + + return n; + } + + virtual int + sync() + { + result.append(pbase(), pptr()); + setp(buffer, buffer + 4); + return 0; + } +}; + +// libstdc++/1057 +void test04() +{ + bool test = true; + std::string text = "abcdefghijklmn"; + + // 01 + setpbuf sp1; + // Here xsputn writes over sp1.result + sp1.sputn(text.c_str(), text.length()); + + // This crashes when result is accessed + sp1.pubsync(); + VERIFY( sp1.get_result() == text ); + + + // 02 + setpbuf sp2; + for (std::string::size_type i = 0; i < text.length(); ++i) + { + // sputc also writes over result + sp2.sputc(text[i]); + } + + // Crash here + sp2.pubsync(); + VERIFY( sp2.get_result() == text ); +} + +class nullsetpbuf : public std::streambuf +{ + char foo[64]; +public: + nullsetpbuf() + { + setp(foo, foo + 64); + setp(NULL, NULL); + } +}; + +// libstdc++/1057 +void test05() +{ + std::string text1 = "abcdefghijklmn"; + + nullsetpbuf nsp; + // Immediate crash as xsputn writes to null pointer + nsp.sputn(text1.c_str(), text1.length()); + // ditto + nsp.sputc('a'); +} int main() { @@ -239,6 +332,8 @@ int main() test02(); test03(); + test04(); + test05(); return 0; } -- 2.30.2