This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] Fix libstdc++/15002 (continued)
- From: Paolo Carlini <pcarlini at suse dot de>
- To: "'gcc-patches at gcc dot gnu dot org'" <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 25 Apr 2004 14:30:59 +0200
- Subject: [v3] Fix libstdc++/15002 (continued)
Hi,
tested x86-linux, committed to mainline.
Paolo.
/////////////
2004-04-24 Paolo Carlini <pcarlini@suse.de>
Petur Runolfsson <peturr02@ru.is>
PR libstdc++/15002 (continued)
* include/bits/istream.tcc (basic_istream<>::getline(char_type*,
streamsize, char_type)): Use traits::find/copy in a loop to speed
up greatly the function in the common case (I/O buffer size >> 1).
2004-04-24 Paolo Carlini <pcarlini@suse.de>
* testsuite/27_io/basic_istream/getline/char/4.cc: New.
* include/bits/istream.tcc (getline(basic_istream<>&,
basic_string<>&, _CharT)): Change to use sgetc()/snextc() instead
of sbumpc(), consistently with the other functions, thus also
dealing correctly with the case of exceeded string::max_size().
diff -prN libstdc++-v3-orig/include/bits/istream.tcc libstdc++-v3/include/bits/istream.tcc
*** libstdc++-v3-orig/include/bits/istream.tcc Sun Feb 8 05:46:41 2004
--- libstdc++-v3/include/bits/istream.tcc Fri Apr 23 12:17:58 2004
***************
*** 1,6 ****
// istream classes -*- C++ -*-
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
--- 1,6 ----
// istream classes -*- C++ -*-
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
*************** namespace std
*** 592,618 ****
const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
int_type __c = __sb->sgetc();
!
! while (_M_gcount + 1 < __n
&& !traits_type::eq_int_type(__c, __eof)
&& !traits_type::eq_int_type(__c, __idelim))
{
! *__s++ = traits_type::to_char_type(__c);
! __c = __sb->snextc();
! ++_M_gcount;
}
if (traits_type::eq_int_type(__c, __eof))
__err |= ios_base::eofbit;
! else
{
! if (traits_type::eq_int_type(__c, __idelim))
! {
! __sb->sbumpc();
! ++_M_gcount;
! }
! else
! __err |= ios_base::failbit;
}
}
catch(...)
{ this->_M_setstate(ios_base::badbit); }
--- 592,636 ----
const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
int_type __c = __sb->sgetc();
! --__n;
!
! while (_M_gcount < __n
&& !traits_type::eq_int_type(__c, __eof)
&& !traits_type::eq_int_type(__c, __idelim))
{
! streamsize __size = std::min(streamsize(__sb->egptr()
! - __sb->gptr()),
! __n - _M_gcount);
! if (__size > 1)
! {
! const char_type* __p = traits_type::find(__sb->gptr(),
! __size,
! __delim);
! if (__p)
! __size = __p - __sb->gptr();
! traits_type::copy(__s, __sb->gptr(), __size);
! __s += __size;
! __sb->gbump(__size);
! _M_gcount += __size;
! __c = __sb->sgetc();
! }
! else
! {
! *__s++ = traits_type::to_char_type(__c);
! __c = __sb->snextc();
! ++_M_gcount;
! }
}
+
if (traits_type::eq_int_type(__c, __eof))
__err |= ios_base::eofbit;
! else if (traits_type::eq_int_type(__c, __idelim))
{
! __sb->sbumpc();
! ++_M_gcount;
}
+ else
+ __err |= ios_base::failbit;
}
catch(...)
{ this->_M_setstate(ios_base::badbit); }
*************** namespace std
*** 1085,1106 ****
try
{
__str.erase();
! __int_type __idelim = _Traits::to_int_type(__delim);
! __streambuf_type* __sb = __in.rdbuf();
! __int_type __c = __sb->sbumpc();
const __int_type __eof = _Traits::eof();
! __testdelim = _Traits::eq_int_type(__c, __idelim);
! while (!_Traits::eq_int_type(__c, __eof) && !__testdelim
! && __extracted < __n)
{
__str += _Traits::to_char_type(__c);
++__extracted;
- __c = __sb->sbumpc();
- __testdelim = _Traits::eq_int_type(__c, __idelim);
}
if (_Traits::eq_int_type(__c, __eof))
__err |= ios_base::eofbit;
}
catch(...)
{
--- 1103,1130 ----
try
{
__str.erase();
! const __int_type __idelim = _Traits::to_int_type(__delim);
const __int_type __eof = _Traits::eof();
! __streambuf_type* __sb = __in.rdbuf();
! __int_type __c = __sb->sgetc();
! while (__extracted < __n
! && !_Traits::eq_int_type(__c, __eof)
! && !_Traits::eq_int_type(__c, __idelim))
{
__str += _Traits::to_char_type(__c);
+ __c = __sb->snextc();
++__extracted;
}
if (_Traits::eq_int_type(__c, __eof))
__err |= ios_base::eofbit;
+ else if (_Traits::eq_int_type(__c, __idelim))
+ {
+ __sb->sbumpc();
+ ++__extracted;
+ }
+ else
+ __err |= ios_base::failbit;
}
catch(...)
{
*************** namespace std
*** 1110,1116 ****
__in._M_setstate(ios_base::badbit);
}
}
! if ((!__extracted && !__testdelim) || __extracted == __n)
__err |= ios_base::failbit;
if (__err)
__in.setstate(__err);
--- 1134,1140 ----
__in._M_setstate(ios_base::badbit);
}
}
! if (!__extracted)
__err |= ios_base::failbit;
if (__err)
__in.setstate(__err);
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_istream/getline/char/4.cc libstdc++-v3/testsuite/27_io/basic_istream/getline/char/4.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_istream/getline/char/4.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_istream/getline/char/4.cc Fri Apr 23 23:39:01 2004
***************
*** 0 ****
--- 1,106 ----
+ // Copyright (C) 2004 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
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ // GNU General Public License for more details.
+
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING. If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction. Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License. This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+
+ #include <cstring> // for strlen
+ #include <istream>
+ #include <testsuite_hooks.h>
+
+ class Inbuf : public std::streambuf
+ {
+ static const char buf[];
+ const char* current;
+ int size;
+
+ public:
+ Inbuf()
+ {
+ current = buf;
+ size = std::strlen(buf);
+ }
+
+ int_type underflow()
+ {
+ if (current < buf + size)
+ return traits_type::to_int_type(*current);
+ return traits_type::eof();
+ }
+
+ int_type uflow()
+ {
+ if (current < buf + size)
+ return traits_type::to_int_type(*current++);
+ return traits_type::eof();
+ }
+ };
+
+ const char Inbuf::buf[] = "1234567890abcdefghij";
+
+ void test01()
+ {
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ typedef char_traits<char> traits_type;
+
+ Inbuf inbuf1;
+ istream is(&inbuf1);
+
+ char buffer[10];
+ traits_type::assign(buffer, sizeof(buffer), 'X');
+
+ is.getline(buffer, sizeof(buffer), '0');
+ VERIFY( is.rdstate() == ios_base::goodbit );
+ VERIFY( !traits_type::compare(buffer, "123456789\0", sizeof(buffer)) );
+ VERIFY( is.gcount() == 10 );
+
+ is.clear();
+ traits_type::assign(buffer, sizeof(buffer), 'X');
+ is.getline(buffer, sizeof(buffer));
+ VERIFY( is.rdstate() == ios_base::failbit );
+ VERIFY( !traits_type::compare(buffer, "abcdefghi\0", sizeof(buffer)) );
+ VERIFY( is.gcount() == 9 );
+
+ is.clear();
+ traits_type::assign(buffer, sizeof(buffer), 'X');
+ is.getline(buffer, sizeof(buffer));
+ VERIFY( is.rdstate() == ios_base::eofbit );
+ VERIFY( !traits_type::compare(buffer, "j\0XXXXXXXX", sizeof(buffer)) );
+ VERIFY( is.gcount() == 1 );
+
+ is.clear();
+ traits_type::assign(buffer, sizeof(buffer), 'X');
+ is.getline(buffer, sizeof(buffer));
+ VERIFY( is.rdstate() == (ios_base::eofbit | ios_base::failbit) );
+ VERIFY( !traits_type::compare(buffer, "\0XXXXXXXXX", sizeof(buffer)) );
+ VERIFY( is.gcount() == 0 );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }