This is the mail archive of the
libstdc++@sources.redhat.com
mailing list for the libstdc++ project.
[PATCH] bits/istream.tcc testsuite/27_io/istream_unformatted.cc
- To: stdc++ <libstdc++ at sourceware dot cygnus dot com>
- Subject: [PATCH] bits/istream.tcc testsuite/27_io/istream_unformatted.cc
- From: brent verner <brent at rcfile dot org>
- Date: Sun, 23 Jul 2000 21:47:59 -0400
This patch corrects the behavior of istream::getline() as well as adding
a couple of tests to verify compliance WRT the modified getline().
2000-07-23 Brent Verner <brent@rcfile.org>
* bits/istream.tcc: istream::getline(char_type*, streamsize, char_type)
make compliant
* testsuite/27_io/istream_unformatted.cc: test for compliant behavior
Index: bits/istream.tcc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/bits/istream.tcc,v
retrieving revision 1.2
diff -c -p -3 -r1.2 istream.tcc
*** istream.tcc 2000/07/07 21:21:57 1.2
--- istream.tcc 2000/07/24 01:31:47
*************** namespace std {
*** 626,674 ****
if (__cerb)
{
try {
const int_type __idelim = traits_type::to_int_type(__delim);
const int_type __eof = traits_type::eof();
! __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)
! {
! int_type __c = __sb->sgetc();
! __testdelim = __c == __idelim;
__testeof = __c == __eof;
! if (__testdelim)
! {
! ++_M_gcount;
! __sb->sbumpc();
! }
! }
! else
! {
! 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
--- 626,653 ----
if (__cerb)
{
try {
+ __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 (!__testeof && ++_M_gcount < __n && !__testdelim){
! *__s++ = traits_type::to_char_type(__c);
! __c = __sb->sbumpc();
__testeof = __c == __eof;
! __testdelim = __c == __idelim;
! }
!
! if(__testeof){
! this->setstate(ios_base::eofbit);
! }
! else if(!__testdelim){
! --_M_gcount;
! __sb->sputbackc(traits_type::to_char_type(__c));
! this->setstate(ios_base::failbit);
! }
}
catch(exception& __fail){
// 27.6.1.3 paragraph 1
*************** namespace std {
*** 678,686 ****
throw;
}
}
! *__s = char_type(NULL);
! if (!_M_gcount)
this->setstate(ios_base::failbit);
return *this;
}
--- 657,665 ----
throw;
}
}
! if(!_M_gcount)
this->setstate(ios_base::failbit);
+ *__s = char_type(NULL);
return *this;
}
Index: testsuite/27_io/istream_unformatted.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/testsuite/27_io/istream_unformatted.cc,v
retrieving revision 1.3
diff -c -p -3 -r1.3 istream_unformatted.cc
*** istream_unformatted.cc 2000/07/07 21:21:57 1.3
--- istream_unformatted.cc 2000/07/24 01:31:50
*************** bool test02(void)
*** 161,173 ****
// istream& getline(char* s, streamsize n, char delim)
// istream& getline(char* s, streamsize n)
! state1 = is_00.rdstate();
is_00.getline(carray1, 20, '*');
! state2 = is_00.rdstate();
! test &= is_04.gcount() == 0;
test &= state1 != state2;
! test &= bool(state2 & statefail);
state1 = is_04.rdstate();
is_04.getline(carray1, 1, '\t'); // extracts, throws away
state2 = is_04.rdstate();
--- 161,175 ----
// istream& getline(char* s, streamsize n, char delim)
// istream& getline(char* s, streamsize n)
! state1 = is_00.rdstate();
is_00.getline(carray1, 20, '*');
! state2 = is_00.rdstate();
! // make sure failbit was set, since we couldn't extract
! // from the NULL streambuf...
test &= state1 != state2;
! test &= static_cast<bool>(state2 & statefail);
+ test &= is_04.gcount() == 0;
state1 = is_04.rdstate();
is_04.getline(carray1, 1, '\t'); // extracts, throws away
state2 = is_04.rdstate();
*************** void test04()
*** 351,357 ****
// http://sourceware.cygnus.com/ml/libstdc++/2000-07/msg00003.html
bool test05()
{
-
const char* charray = "
a
aa
--- 353,358 ----
*************** aaaaaaaaaaaaaa
*** 376,415 ****
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;
}
--- 377,437 ----
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 a sanity check to make sure we've extracted the same
! // number of chars that were in the streambuf
! 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() )
{
! // delimiter not read
! //
! // either
! // -> extracted no characters
! // or
! // -> n - 1 characters are stored
ifs.clear(ifs.rdstate() & ~std::ios::failbit);
! VERIFY( (ifs.gcount() == 0) || (strlen(tmp) == it - 1) );
! VERIFY( ifs );
continue;
}
else
{
! // delimiter was read.
! //
! // make sure it was extracted/counted, but not stored.
! VERIFY( ifs.gcount() == strlen(tmp) + 1 );
continue;
}
}
+
+ // http://sources.redhat.com/ml/libstdc++/2000-07/msg00126.html
+ const std::streamsize it1 = 5;
+ char tmp1[it1];
+ const char* str_lit = "abcd\n";
+
+ std::stringbuf strbuf(str_lit, std::ios_base::in);
+ std::istream istr(&strbuf);
+
+ istr.getline(tmp1, it1);
+ VERIFY( istr.gcount() == it1 ); // extracted whole string
+ VERIFY( strlen(tmp1) == 4 ); // stored all but '\n'
+ VERIFY( !istr.eof() ); // extracted up to but not eof
+ VERIFY( !istr.fail() ); // failbit not set
+
+ char c = 'z';
+ istr.get(c);
+ VERIFY( c == 'z' );
+ VERIFY( istr.eof() );
return 0;
}
--
Damon Brent Verner o _ _ _
Cracker Jack? Surprise Certified _o /\_ _ \\o (_)\__/o (_)
brent@rcfile.org _< \_ _>(_) (_)/<_ \_| \ _|/' \/
brent@linux1.org (_)>(_) (_) (_) (_) (_)' _\o_