C++STYLE (classname): Add more existing and stylish patterns.

2001-01-16  Benjamin Kosnik  <bkoz@redhat.com>

	* 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 <pcarlini@unitus.it>
	* 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 <jcampbell3@prodigy.net>
	* include/bits/streambuf.tcc (streambuf::xsputn): Just check for
	equality with eof on returned value from overflow.

From-SVN: r39059
This commit is contained in:
Benjamin Kosnik 2001-01-16 07:55:26 +00:00 committed by Benjamin Kosnik
parent 6488ac06d9
commit 13187a454d
11 changed files with 344 additions and 162 deletions

View File

@ -1,3 +1,29 @@
2001-01-16 Benjamin Kosnik <bkoz@redhat.com>
* 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 <pcarlini@unitus.it>
* 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 <jcampbell3@prodigy.net>
* include/bits/streambuf.tcc (streambuf::xsputn): Just check for
equality with eof on returned value from overflow.
2001-01-14 Andreas Jaeger <aj@suse.de>
* libio/libio.h: Add test for glibc 2.0.

View File

@ -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<char>::ctype(const mask* __table, bool __del, size_t __refs) :
__ctype_abstract_base<char>(__refs), _M_del(__table != 0 && __del),
_M_toupper(__ctype_toupper), _M_tolower(__ctype_tolower),
_M_ctable(static_cast<const mask*>(__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<typename T> // notice: "typename", not "class", no space
long_return_value_type<with_many, args>
function_name(char* pointer, // "char *pointer" is wrong.
@ -321,8 +348,8 @@ namespace std {
{
// doesn't fit in one line.
}
}
} // namespace std

View File

@ -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<typename _CharT, typename _Traits>
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<typename _CharT, typename _Traits>
@ -86,13 +91,13 @@ namespace std
template<typename _CharT, typename _Traits>
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;
}

View File

@ -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<typename _CharT, typename _Traits>
@ -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;

View File

@ -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<typename _CharT, typename _Traits>
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<int_type>(__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<int_type>(__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);

View File

@ -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 {

View File

@ -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 <sstream>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <debug_assert.h>
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;
}

View File

@ -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

View File

@ -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
}
// libstdc++/944
void
test02()
{
using namespace std;
istringstream in("80.21 56.89 12.3");
bool test = true;
int i = 0;
double x;
int main() {
// ios_base::eof == 2
while(in >> x)
{
++i;
}
VERIFY( i == 3 );
}
int main()
{
test01();
test02();
return 0;
}

View File

@ -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)

View File

@ -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 <cstring> // for memset, memcmp
#include <streambuf>
#include <string>
#include <ostream>
#include <debug_assert.h>
@ -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;
}