sentry __cerb(*this, true);
if (__cerb)
{
- const int_type __eof = traits_type::eof();
- int_type __bufval;
try {
- __bufval = this->rdbuf()->sbumpc();
+ const int_type __eof = traits_type::eof();
+ int_type __bufval = this->rdbuf()->sbumpc();
// 27.6.1.1 paragraph 3
if (__bufval != __eof)
{
if (__cerb && __n > 1)
{
try {
- int_type __idelim = traits_type::to_int_type(__delim);
+ const int_type __idelim = traits_type::to_int_type(__delim);
+ const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
int_type __c = __sb->sbumpc();
- const int_type __eof = traits_type::eof();
bool __testdelim = __c == __idelim;
bool __testeof = __c == __eof;
sentry __cerb(*this, true);
if (__cerb)
{
- __streambuf_type* __this_sb = this->rdbuf();
int_type __c;
+ __streambuf_type* __this_sb = this->rdbuf();
try {
- int_type __idelim = traits_type::to_int_type(__delim);
- __c = __this_sb->sbumpc();
+ const int_type __idelim = traits_type::to_int_type(__delim);
const int_type __eof = traits_type::eof();
+ __c = __this_sb->sbumpc();
bool __testdelim = __c == __idelim;
bool __testeof = __c == __eof;
bool __testput = true;
if (__cerb)
{
try {
- int_type __idelim = traits_type::to_int_type(__delim);
- __streambuf_type* __sb = this->rdbuf();
- int_type __c = __sb->sbumpc();
+ const int_type __idelim = traits_type::to_int_type(__delim);
const int_type __eof = traits_type::eof();
- bool __testdelim = __c == __idelim;
- bool __testeof = __c == __eof;
-
- while (_M_gcount < __n - 1 && !__testeof && !__testdelim)
+ __streambuf_type* __sb = this->rdbuf();
+ bool __testdelim = false;
+ bool __testeof = false;
+
+ // This is completely idiotic, but attempts to recreate
+ // the smoke-filled air of the committee meeting where
+ // getline was defined. It's unspecified for __n == 1,
+ // what happens to the extracted char if it is not a
+ // delimiter or EOF. Assume it's not extracted, for the
+ // time being. . .
+ if (__n == 1)
{
- *__s++ = traits_type::to_char_type(__c);
- ++_M_gcount;
- __c = __sb->sbumpc();
- __testeof = __c == __eof;
+ int_type __c = __sb->sgetc();
__testdelim = __c == __idelim;
+ __testeof = __c == __eof;
+ if (__testdelim)
+ {
+ ++_M_gcount;
+ __sb->sbumpc();
+ }
}
- if (_M_gcount == __n - 1 && !__testeof && !__testdelim)
+ else
{
- __sb->sputbackc(traits_type::to_char_type(__c));
- this->setstate(ios_base::failbit);
- }
- if (__testdelim)
- ++_M_gcount;
+ while (_M_gcount < __n - 1 && !__testdelim && !__testeof)
+ {
+ int_type __c = __sb->sbumpc();
+ __testdelim = __c == __idelim;
+ __testeof = __c == __eof;
+ if (__testdelim)
+ ++_M_gcount;
+ else if (!__testeof)
+ {
+ *__s++ = traits_type::to_char_type(__c);
+ ++_M_gcount;
+ }
+ }
+ }
if (__testeof)
this->setstate(ios_base::eofbit);
+ else if (!__testdelim && _M_gcount == __n - 1)
+ this->setstate(ios_base::failbit);
}
catch(exception& __fail){
// 27.6.1.3 paragraph 1
}
}
*__s = char_type(NULL);
- if (!_M_gcount || _M_gcount == __n - 1)
+ if (!_M_gcount)
this->setstate(ios_base::failbit);
return *this;
}
if (__cerb && __n > 0)
{
try {
- int_type __idelim = traits_type::to_int_type(__delim);
+ const int_type __idelim = traits_type::to_int_type(__delim);
+ const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
int_type __c = __sb->sbumpc();
- const int_type __eof = traits_type::eof();
bool __testdelim = __c == __idelim;
bool __testeof = __c == __eof;
if (__n > 0)
{
try {
+ const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
int_type __c = __sb->sbumpc();
- const int_type __eof = traits_type::eof();
bool __testeof = __c == __eof;
while (_M_gcount < __n - 1 && !__testeof)
basic_istream<_CharT, _Traits>::
unget(void)
{
- const int_type __eof = traits_type::eof();
_M_gcount = 0;
sentry __cerb(*this, true);
if (__cerb)
{
try {
+ const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
if (!__sb || __eof == __sb->sungetc())
this->setstate(ios_base::badbit);
#include <sstream>
#include <fstream>
#ifdef DEBUG_ASSERT
- #include <assert.h>
+#include <cassert>
+# define VERIFY(fn) assert(fn)
+#else
+# define VERIFY(fn)
#endif
bool test01() {
}
// http://sourceware.cygnus.com/ml/libstdc++/2000-q1/msg00177.html
-void test06()
+void test04()
{
bool test = true;
#endif
}
+// http://sourceware.cygnus.com/ml/libstdc++/2000-07/msg00003.html
+bool test05()
+{
+
+ const char* charray = "
+a
+aa
+aaa
+aaaa
+aaaaa
+aaaaaa
+aaaaaaa
+aaaaaaaa
+aaaaaaaaa
+aaaaaaaaaa
+aaaaaaaaaaa
+aaaaaaaaaaaa
+aaaaaaaaaaaaa
+aaaaaaaaaaaaaa
+";
+
+ bool test = true;
+ const std::streamsize it = 5;
+ std::streamsize br = 0;
+ char tmp[it];
+ std::stringbuf sb(charray, std::ios_base::in);
+ std::istream ifs(&sb);
+ std::streamsize blen = strlen(charray);
+ VERIFY(ifs);
+ while(ifs.getline(tmp, it) || ifs.gcount())
+ {
+ br += ifs.gcount();
+ if(ifs.eof())
+ {
+ // Just sanity checks to make sure we've extracted the same
+ // number of chars that were in the file.
+ VERIFY(br == blen);
+ // Also, we should only set the failbit if we could
+ // _extract_ no chars from the stream, i.e. the first read
+ // returned EOF.
+ VERIFY(ifs.fail() && ifs.gcount() == 0);
+ }
+ else if(ifs.fail())
+ {
+ // either
+ // -> extracted no characters
+ // or
+ // -> n - 1 characters are stored
+ VERIFY(strlen(tmp) == it - 1);
+ ifs.clear(ifs.rdstate() & ~std::ios::failbit);
+ VERIFY(ifs);
+ continue;
+ }
+ else
+ {
+ // -> strlen(__s) < n - 1
+ // -> delimiter was seen -> gcount() > strlen(__s)
+ VERIFY(ifs.gcount() > strlen(tmp));
+ VERIFY(it - 1 > strlen(tmp));
+ continue;
+ }
+ }
+
+ return 0;
+}
+
int main()
{
test01();
test02();
test03();
- test06();
+ test04();
+ test05();
return 0;
}