diff options
author | Howard Hinnant <hhinnant@apple.com> | 2011-09-01 21:02:45 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2011-09-01 21:02:45 +0000 |
commit | 00d8c245b26d74415a712cb99687ac9ffe01fbf4 (patch) | |
tree | 101d4b29b7440503b856ad115b12a8c83d283aa5 /libcxx | |
parent | cbbc0141f6c1bcae309ebaaa100cfd03c4386c52 (diff) | |
download | bcm5719-llvm-00d8c245b26d74415a712cb99687ac9ffe01fbf4.tar.gz bcm5719-llvm-00d8c245b26d74415a712cb99687ac9ffe01fbf4.zip |
Reimplemented much of <istream> such that single character extractions do not check to see if this is the last character in the stream and thus never set eofbit. This fixes http://llvm.org/bugs/show_bug.cgi?id=10817 . This fix requires a recompiled libc++.dylib to be fully implemented. The recompiled libc++.dylib is ABI compatible with that shipped on Lion.
llvm-svn: 138961
Diffstat (limited to 'libcxx')
6 files changed, 177 insertions, 217 deletions
diff --git a/libcxx/include/istream b/libcxx/include/istream index c56393acbee..de8aa106723 100644 --- a/libcxx/include/istream +++ b/libcxx/include/istream @@ -742,26 +742,29 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) typename basic_istream<_CharT, _Traits>::sentry __sen(__is); if (__sen) { - typedef istreambuf_iterator<_CharT, _Traits> _I; streamsize __n = __is.width(); - if (__n == 0) + if (__n <= 0) __n = numeric_limits<streamsize>::max() / sizeof(_CharT) - 1; streamsize __c = 0; const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc()); - _I __i(__is); - _I __eof; - for (; __i != __eof && __c < __n-1; ++__i, ++__s, ++__c) + ios_base::iostate __err = ios_base::goodbit; + while (__c < __n-1) { - _CharT __ch = *__i; + typename _Traits::int_type __i = __is.rdbuf()->sgetc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + { + __err |= ios_base::eofbit; + break; + } + _CharT __ch = _Traits::to_char_type(__i); if (__ct.is(__ct.space, __ch)) break; - *__s = __ch; + *__s++ = __ch; + ++__c; + __is.rdbuf()->sbumpc(); } *__s = _CharT(); __is.width(0); - ios_base::iostate __err = ios_base::goodbit; - if (__i == __eof) - __err |= ios_base::eofbit; if (__c == 0) __err |= ios_base::failbit; __is.setstate(__err); @@ -803,25 +806,11 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c) typename basic_istream<_CharT, _Traits>::sentry __sen(__is); if (__sen) { -#if 1 typename _Traits::int_type __i = __is.rdbuf()->sbumpc(); if (_Traits::eq_int_type(__i, _Traits::eof())) __is.setstate(ios_base::eofbit | ios_base::failbit); else __c = _Traits::to_char_type(__i); -#else - typedef istreambuf_iterator<_CharT, _Traits> _I; - _I __i(__is); - _I __eof; - if (__i != __eof) - { - __c = *__i; - if (++__i == __eof) - __is.setstate(ios_base::eofbit); - } - else - __is.setstate(ios_base::eofbit | ios_base::failbit); -#endif } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -861,42 +850,42 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ sentry __s(*this, true); if (__s) { - streamsize __c = 0; if (__sb) { #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - typedef istreambuf_iterator<char_type, traits_type> _I; - typedef ostreambuf_iterator<char_type, traits_type> _O; - _I __i(*this); - _I __eof; - _O __o(__sb); - for (; __i != __eof; ++__i, ++__o, ++__c) + ios_base::iostate __err = ios_base::goodbit; + while (true) { - *__o = *__i; - if (__o.failed()) + typename traits_type::int_type __i = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__i, _Traits::eof())) + { + __err |= ios_base::eofbit; + break; + } + if (traits_type::eq_int_type( + __sb->sputc(traits_type::to_char_type(__i)), + traits_type::eof())) break; + ++__gc_; + this->rdbuf()->sbumpc(); } - ios_base::iostate __err = ios_base::goodbit; - if (__i == __eof) - __err |= ios_base::eofbit; - if (__c == 0) + if (__gc_ == 0) __err |= ios_base::failbit; this->setstate(__err); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - if (__c == 0) + if (__gc_ == 0) this->__set_failbit_and_consider_rethrow(); } #endif // _LIBCPP_NO_EXCEPTIONS } else this->setstate(ios_base::failbit); - __gc_ = __c; } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -921,22 +910,11 @@ basic_istream<_CharT, _Traits>::get() sentry __s(*this, true); if (__s) { - streamsize __c = 0; - typedef istreambuf_iterator<char_type, traits_type> _I; - _I __i(*this); - _I __eof; - ios_base::iostate __err = ios_base::goodbit; - if (__i != __eof) - { - __r = traits_type::to_int_type(*__i); - ++__c; - if (++__i == __eof) - __err |= ios_base::eofbit; - } + __r = this->rdbuf()->sbumpc(); + if (traits_type::eq_int_type(__r, traits_type::eof())) + this->setstate(ios_base::failbit | ios_base::eofbit); else - __err |= ios_base::failbit | ios_base::eofbit; - this->setstate(__err); - __gc_ = __c; + __gc_ = 1; } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -971,30 +949,31 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __ sentry __sen(*this, true); if (__sen) { - streamsize __c = 0; if (__n > 0) { - typedef istreambuf_iterator<char_type, traits_type> _I; - _I __i(*this); - _I __eof; - for (; __i != __eof && __n > 1; ++__i, ++__s, ++__c) + ios_base::iostate __err = ios_base::goodbit; + while (__gc_ < __n-1) { - char_type __ch = *__i; + int_type __i = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + __err |= ios_base::eofbit; + break; + } + char_type __ch = traits_type::to_char_type(__i); if (traits_type::eq(__ch, __dlm)) break; - *__s = __ch; + *__s++ = __ch; + ++__gc_; + this->rdbuf()->sbumpc(); } *__s = char_type(); - ios_base::iostate __err = ios_base::goodbit; - if (__i == __eof) - __err |= ios_base::eofbit; - if (__c == 0) + if (__gc_ == 0) __err |= ios_base::failbit; this->setstate(__err); } else this->setstate(ios_base::failbit); - __gc_ = __c; } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -1027,38 +1006,36 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __s sentry __sen(*this, true); if (__sen) { - streamsize __c = 0; ios_base::iostate __err = ios_base::goodbit; #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - typedef istreambuf_iterator<char_type, traits_type> _I; - typedef ostreambuf_iterator<char_type, traits_type> _O; - _I __i(*this); - _I __eof; - _O __o(&__sb); - for (; __i != __eof; ++__i, ++__o, ++__c) + while (true) { - char_type __ch = *__i; + typename traits_type::int_type __i = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + __err |= ios_base::eofbit; + break; + } + char_type __ch = traits_type::to_char_type(__i); if (traits_type::eq(__ch, __dlm)) break; - *__o = __ch; - if (__o.failed()) + if (traits_type::eq_int_type(__sb.sputc(__ch), traits_type::eof())) break; + ++__gc_; + this->rdbuf()->sbumpc(); } - if (__i == __eof) - __err |= ios_base::eofbit; #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { } #endif // _LIBCPP_NO_EXCEPTIONS - if (__c == 0) + if (__gc_ == 0) __err |= ios_base::failbit; this->setstate(__err); - __gc_ = __c; } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -1090,33 +1067,36 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ sentry __sen(*this, true); if (__sen) { - streamsize __c = 0; - typedef istreambuf_iterator<char_type, traits_type> _I; - _I __i(*this); - _I __eof; - for (; __i != __eof; ++__s, --__n) + ios_base::iostate __err = ios_base::goodbit; + while (true) { - char_type __ch = *__i; - ++__i; - ++__c; + typename traits_type::int_type __i = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + __err |= ios_base::eofbit; + break; + } + char_type __ch = traits_type::to_char_type(__i); if (traits_type::eq(__ch, __dlm)) + { + this->rdbuf()->sbumpc(); + ++__gc_; break; - if (__n < 2) + } + if (__gc_ >= __n-1) { - this->setstate(ios_base::failbit); + __err |= ios_base::failbit; break; } - *__s = __ch; + *__s++ = __ch; + this->rdbuf()->sbumpc(); + ++__gc_; } - if (__n) + if (__n > 0) *__s = char_type(); - ios_base::iostate __err = ios_base::goodbit; - if (__i == __eof) - __err |= ios_base::eofbit; - if (__c == 0) + if (__gc_ == 0) __err |= ios_base::failbit; this->setstate(__err); - __gc_ = __c; } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -1148,35 +1128,40 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm) sentry __sen(*this, true); if (__sen) { - streamsize __c = 0; - typedef istreambuf_iterator<char_type, traits_type> _I; - _I __i(*this); - _I __eof; - if (__n != numeric_limits<streamsize>::max()) + ios_base::iostate __err = ios_base::goodbit; + if (__n == numeric_limits<streamsize>::max()) { - for (; __n > 0 && __i != __eof; --__n) + while (true) { - char_type __ch = *__i; - ++__i; - ++__c; + typename traits_type::int_type __i = this->rdbuf()->sbumpc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + __err |= ios_base::eofbit; + break; + } + ++__gc_; + char_type __ch = traits_type::to_char_type(__i); if (traits_type::eq(__ch, __dlm)) break; } } else { - while (__i != __eof) + while (__gc_ < __n) { - char_type __ch = *__i; - ++__i; - ++__c; + typename traits_type::int_type __i = this->rdbuf()->sbumpc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + __err |= ios_base::eofbit; + break; + } + ++__gc_; + char_type __ch = traits_type::to_char_type(__i); if (traits_type::eq(__ch, __dlm)) break; } } - if (__i == __eof) - this->setstate(ios_base::eofbit); - __gc_ = __c; + this->setstate(__err); } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -1223,20 +1208,17 @@ basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) sentry __sen(*this, true); if (__sen) { - streamsize __c = 0; - typedef istreambuf_iterator<char_type, traits_type> _I; - _I __i(*this); - _I __eof; - for (; __i != __eof && __n > 0; ++__i, ++__s, ++__c, --__n) - *__s = *__i; - if (__i == __eof) + ios_base::iostate __err = ios_base::goodbit; + for (; __gc_ < __n; ++__gc_) { - ios_base::iostate __err = ios_base::eofbit; - if (__n > 0) - __err |= ios_base::failbit; - this->setstate(__err); + typename traits_type::int_type __i = this->rdbuf()->sbumpc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + this->setstate(ios_base::failbit | ios_base::eofbit); + break; + } + *__s++ = traits_type::to_char_type(__i); } - __gc_ = __c; } else this->setstate(ios_base::failbit); @@ -1254,45 +1236,19 @@ template<class _CharT, class _Traits> streamsize basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n) { - __gc_ = 0; - streamsize __c = 0; -#ifndef _LIBCPP_NO_EXCEPTIONS - try + streamsize __c = this->rdbuf()->in_avail(); + switch (__c) { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __sen(*this, true); - if (__sen) - { - typedef istreambuf_iterator<char_type, traits_type> _I; - _I __i(*this); - _I __eof; - __c = this->rdbuf()->in_avail(); - switch (__c) - { - case -1: - __i = __eof; - break; - case 0: - break; - default: - __c = _VSTD::min(__c, __n); - for (streamsize __k = 0; __k < __c; ++__k, ++__s, ++__i) - *__s = *__i; - } - if (__i == __eof) - this->setstate(ios_base::eofbit); - __gc_ = __c; - } - else - this->setstate(ios_base::failbit); -#ifndef _LIBCPP_NO_EXCEPTIONS + case -1: + this->setstate(ios_base::eofbit); + break; + case 0: + break; + default: + read(__s, _VSTD::min(__c, __n)); + break; } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return __c; + return __gc_; } template<class _CharT, class _Traits> @@ -1455,15 +1411,19 @@ ws(basic_istream<_CharT, _Traits>& __is) typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true); if (__sen) { - typedef istreambuf_iterator<_CharT, _Traits> _I; const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc()); - _I __i(__is); - _I __eof; - for (; __i != __eof; ++__i) - if (!__ct.is(__ct.space, *__i)) + while (true) + { + typename _Traits::int_type __i = __is.rdbuf()->sgetc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + { + __is.setstate(ios_base::eofbit); + break; + } + if (!__ct.is(__ct.space, _Traits::to_char_type(__i))) break; - if (__i == __eof) - __is.setstate(ios_base::failbit | ios_base::eofbit); + __is.rdbuf()->sbumpc(); + } } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -1572,27 +1532,30 @@ operator>>(basic_istream<_CharT, _Traits>& __is, if (__sen) { __str.clear(); - typedef istreambuf_iterator<_CharT, _Traits> _I; streamsize __n = __is.width(); - if (__n == 0) + if (__n <= 0) __n = __str.max_size(); - if (__n < 0) + if (__n <= 0) __n = numeric_limits<streamsize>::max(); streamsize __c = 0; const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc()); - _I __i(__is); - _I __eof; - for (; __i != __eof && __c < __n; ++__i, ++__c) + ios_base::iostate __err = ios_base::goodbit; + while (__c < __n) { - _CharT __ch = *__i; + typename _Traits::int_type __i = __is.rdbuf()->sgetc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + { + __err |= ios_base::eofbit; + break; + } + _CharT __ch = _Traits::to_char_type(__i); if (__ct.is(__ct.space, __ch)) break; __str.push_back(__ch); + ++__c; + __is.rdbuf()->sbumpc(); } __is.width(0); - ios_base::iostate __err = ios_base::goodbit; - if (__i == __eof) - __err |= ios_base::eofbit; if (__c == 0) __err |= ios_base::failbit; __is.setstate(__err); @@ -1622,31 +1585,26 @@ getline(basic_istream<_CharT, _Traits>& __is, if (__sen) { __str.clear(); - streamsize __c = 0; - typedef istreambuf_iterator<_CharT, _Traits> _I; - _I __i(__is); - _I __eof; - streamsize __n = __str.max_size(); - if (__n < 0) - __n = numeric_limits<streamsize>::max(); - for (; __i != __eof;) + ios_base::iostate __err = ios_base::goodbit; + while (true) { - _CharT __ch = *__i; - ++__i; - ++__c; + typename _Traits::int_type __i = __is.rdbuf()->sbumpc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + { + __err |= ios_base::eofbit; + break; + } + _CharT __ch = _Traits::to_char_type(__i); if (_Traits::eq(__ch, __dlm)) break; - if (__c == __n) + __str.push_back(__ch); + if (__str.size() == __str.max_size()) { - __is.setstate(ios_base::failbit); + __err |= ios_base::failbit; break; } - __str.push_back(__ch); } - ios_base::iostate __err = ios_base::goodbit; - if (__i == __eof) - __err |= ios_base::eofbit; - if (__c == 0) + if (__str.empty()) __err |= ios_base::failbit; __is.setstate(__err); } @@ -1704,24 +1662,26 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x) { basic_string<_CharT, _Traits> __str; const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc()); - typedef istreambuf_iterator<_CharT, _Traits> _I; streamsize __c = 0; + ios_base::iostate __err = ios_base::goodbit; _CharT __zero = __ct.widen('0'); _CharT __one = __ct.widen('1'); - _I __i(__is); - _I __eof; - for (; __i != __eof && __c < _Size; ++__i, ++__c) + while (__c < _Size) { - _CharT __ch = *__i; - if (__ch != __zero && __ch != __one) + typename _Traits::int_type __i = __is.rdbuf()->sgetc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + { + __err |= ios_base::eofbit; + break; + } + _CharT __ch = _Traits::to_char_type(__i); + if (!_Traits::eq(__ch, __zero) && !_Traits::eq(__ch, __one)) break; __str.push_back(__ch); + ++__c; + __is.rdbuf()->sbumpc(); } - __is.width(0); __x = bitset<_Size>(__str); - ios_base::iostate __err = ios_base::goodbit; - if (__i == __eof) - __err |= ios_base::eofbit; if (__c == 0) __err |= ios_base::failbit; __is.setstate(__err); diff --git a/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp b/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp index c8deda37d9d..41a721d50f1 100644 --- a/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp +++ b/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp @@ -68,7 +68,7 @@ int main() assert(c == 'b'); assert(is.gcount() == 1); c = is.get(); - assert( is.eof()); + assert(!is.eof()); assert(!is.fail()); assert(c == 'c'); assert(is.gcount() == 1); @@ -92,7 +92,7 @@ int main() assert(c == L'b'); assert(is.gcount() == 1); c = is.get(); - assert( is.eof()); + assert(!is.eof()); assert(!is.fail()); assert(c == L'c'); assert(is.gcount() == 1); diff --git a/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp b/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp index 15dd949967a..cf06e343bcc 100644 --- a/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp +++ b/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp @@ -70,7 +70,7 @@ int main() assert(c == 'b'); assert(is.gcount() == 1); is.get(c); - assert( is.eof()); + assert(!is.eof()); assert(!is.fail()); assert(c == 'c'); assert(is.gcount() == 1); @@ -95,7 +95,7 @@ int main() assert(c == L'b'); assert(is.gcount() == 1); is.get(c); - assert( is.eof()); + assert(!is.eof()); assert(!is.fail()); assert(c == L'c'); assert(is.gcount() == 1); diff --git a/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp b/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp index 2060ff21bd7..20e70cfbd5c 100644 --- a/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp +++ b/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp @@ -50,7 +50,7 @@ int main() assert(std::string(s, 5) == " 1234"); assert(is.gcount() == 5); is.read(s, 5); - assert( is.eof()); + assert(!is.eof()); assert(!is.fail()); assert(std::string(s, 5) == "56789"); assert(is.gcount() == 5); @@ -69,7 +69,7 @@ int main() assert(std::wstring(s, 5) == L" 1234"); assert(is.gcount() == 5); is.read(s, 5); - assert( is.eof()); + assert(!is.eof()); assert(!is.fail()); assert(std::wstring(s, 5) == L"56789"); assert(is.gcount() == 5); diff --git a/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp b/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp index 46446689596..fe853d3a492 100644 --- a/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp +++ b/libcxx/test/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp @@ -55,7 +55,7 @@ int main() assert(std::string(s, 5) == "56789"); assert(is.gcount() == 5); is.readsome(s, 5); - assert( is.eof()); + assert(!is.eof()); assert(!is.fail()); assert(is.gcount() == 1); assert(std::string(s, 1) == "0"); @@ -75,7 +75,7 @@ int main() assert(std::wstring(s, 5) == L"56789"); assert(is.gcount() == 5); is.readsome(s, 5); - assert( is.eof()); + assert(!is.eof()); assert(!is.fail()); assert(is.gcount() == 1); assert(std::wstring(s, 1) == L"0"); diff --git a/libcxx/test/numerics/complex.number/complex.ops/stream_input.pass.cpp b/libcxx/test/numerics/complex.number/complex.ops/stream_input.pass.cpp index f3c0f5244b1..24644e30779 100644 --- a/libcxx/test/numerics/complex.number/complex.ops/stream_input.pass.cpp +++ b/libcxx/test/numerics/complex.number/complex.ops/stream_input.pass.cpp @@ -87,13 +87,13 @@ int main() std::complex<double> c; is >> c; assert(c == std::complex<double>(-5.5, -6.5)); - assert(is.eof()); + assert(!is.eof()); } { std::istringstream is("(-5.5,-6.5)"); std::complex<double> c; is >> c; assert(c == std::complex<double>(-5.5, -6.5)); - assert(is.eof()); + assert(!is.eof()); } } |