aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2003-11-22 09:54:25 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2003-11-22 09:54:25 +0000
commit1a311979dd85c3a98a58f02b700dd7e1b6465945 (patch)
tree8e79787849bb704bf36b58897c382cf4b682c6e1
parent13418b400379006a6536465c774aa33a4871f398 (diff)
downloadgcc-1a311979dd85c3a98a58f02b700dd7e1b6465945.zip
gcc-1a311979dd85c3a98a58f02b700dd7e1b6465945.tar.gz
gcc-1a311979dd85c3a98a58f02b700dd7e1b6465945.tar.bz2
re PR libstdc++/12593 (Resolution of DR 91 (WP) still unimplemented)
2003-11-22 Paolo Carlini <pcarlini@suse.de> PR libstdc++/12593 * include/bits/istream.tcc (operator>>(basic_string<>&), getline(basic_string<>&)): Implement resolution of DR 91 [WP]; fix some minor issues with the exit conditions. * docs/html/ext/howto.html: Add an entry for DR 91. From-SVN: r73835
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/docs/html/ext/howto.html9
-rw-r--r--libstdc++-v3/include/bits/istream.tcc101
3 files changed, 81 insertions, 37 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 6f9fab4..22c9b0c 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2003-11-22 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/12593
+ * include/bits/istream.tcc (operator>>(basic_string<>&),
+ getline(basic_string<>&)): Implement resolution of DR 91 [WP];
+ fix some minor issues with the exit conditions.
+ * docs/html/ext/howto.html: Add an entry for DR 91.
+
2003-11-21 Paolo Carlini <pcarlini@suse.de>
* config/locale/gnu/monetary_members.cc
diff --git a/libstdc++-v3/docs/html/ext/howto.html b/libstdc++-v3/docs/html/ext/howto.html
index 336abd7..82930a8 100644
--- a/libstdc++-v3/docs/html/ext/howto.html
+++ b/libstdc++-v3/docs/html/ext/howto.html
@@ -526,6 +526,15 @@
replaced by <code>isspace(c,is.getloc())</code>.
</dd>
+ <dt><a href="lwg-defects.html#91">91</a>:
+ <em>Description of operator&gt;&gt; and getline() for string&lt;&gt;
+ might cause endless loop</em>
+ </dt>
+ <dd>They behave as a formatted input function and as an unformatted
+ input function, respectively (except that <code>getline</code> is
+ not required to set <code>gcount</code>).
+ </dd>
+
<dt><a href="lwg-defects.html#109">109</a>:
<em>Missing binders for non-const sequence elements</em>
</dt>
diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc
index c455200..40acf11 100644
--- a/libstdc++-v3/include/bits/istream.tcc
+++ b/libstdc++-v3/include/bits/istream.tcc
@@ -1102,32 +1102,46 @@ namespace std
typedef typename __istream_type::__ctype_type __ctype_type;
typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
typedef typename __string_type::size_type __size_type;
- __size_type __extracted = 0;
+ __size_type __extracted = 0;
typename __istream_type::sentry __cerb(__in, false);
if (__cerb)
{
- __str.erase();
- streamsize __w = __in.width();
- __size_type __n;
- __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size();
-
- const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
- 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)
- && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
+ try
{
- __str += _Traits::to_char_type(__c);
- ++__extracted;
- __c = __sb->snextc();
+ __str.erase();
+ streamsize __w = __in.width();
+ __size_type __n;
+ __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size();
+
+ const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
+ 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)
+ && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
+ {
+ __str += _Traits::to_char_type(__c);
+ ++__extracted;
+ __c = __sb->snextc();
+ }
+ if (_Traits::eq_int_type(__c, __eof))
+ __in.setstate(ios_base::eofbit);
+ __in.width(0);
+ }
+ catch(...)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 91. Description of operator>> and getline() for string<>
+ // might cause endless loop
+ // 27.6.1.2.1 Common requirements.
+ // Turn this on without causing an ios::failure to be thrown.
+ __in.setstate(ios_base::badbit);
+ if ((__in.exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
}
- if (_Traits::eq_int_type(__c, __eof))
- __in.setstate(ios_base::eofbit);
- __in.width(0);
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 211. operator>>(istream&, string&) doesn't set failbit
@@ -1149,31 +1163,44 @@ namespace std
typedef typename __string_type::size_type __size_type;
__size_type __extracted = 0;
+ const __size_type __n = __str.max_size();
bool __testdelim = false;
typename __istream_type::sentry __cerb(__in, true);
if (__cerb)
{
- __str.erase();
- __size_type __n = __str.max_size();
-
- __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 (__extracted <= __n && !_Traits::eq_int_type(__c, __eof)
- && !__testdelim)
+ try
{
- __str += _Traits::to_char_type(__c);
- ++__extracted;
- __c = __sb->sbumpc();
+ __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))
+ __in.setstate(ios_base::eofbit);
+ }
+ catch(...)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 91. Description of operator>> and getline() for string<>
+ // might cause endless loop
+ // 27.6.1.2.1 Common requirements.
+ // Turn this on without causing an ios::failure to be thrown.
+ __in.setstate(ios_base::badbit);
+ if ((__in.exceptions() & ios_base::badbit) != 0)
+ __throw_exception_again;
}
- if (_Traits::eq_int_type(__c, __eof))
- __in.setstate(ios_base::eofbit);
}
- if (!__extracted && !__testdelim)
+ if ((!__extracted && !__testdelim) || __extracted == __n)
__in.setstate(ios_base::failbit);
return __in;
}