+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.
-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,
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);
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
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; }
#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.
{
// doesn't fit in one line.
}
+} // 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>
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;
{
_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;
#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;
}
-// 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
#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>
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;
// 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
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);
// 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.
}
}
+ // 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.
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)
}
}
+ // 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
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);
_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:
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);
// 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
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
__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;
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
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);
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;
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
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();
}
return __ret;
}
-
} // namespace std
#endif // _CPP_BITS_STREAMBUF_TCC
+
// 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
#include <sstream>
#include <fstream>
#include <iostream>
+#include <iomanip>
#include <debug_assert.h>
bool test01(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();
test06();
test07();
+ test08();
return 0;
}
// 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
VERIFY( !iss02.eof() );
iss01 >> std::ws;
- VERIFY( !iss01.fail() );
+ VERIFY( iss01.fail() );
VERIFY( iss01.eof() );
#ifdef DEBUG_ASSERT
// 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
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;
}
// 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
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)
// 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
#include <cstring> // for memset, memcmp
#include <streambuf>
+#include <string>
#include <ostream>
#include <debug_assert.h>
#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()
{
test02();
test03();
+ test04();
+ test05();
return 0;
}