From 1deba98bd23b18dbaf4da0e42ee3d5d6c48fe758 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 7 Mar 2003 23:06:28 +0100 Subject: [PATCH] re PR libstdc++/9182 (basic_filebuf<> does not report errors in codecvt<>::out) 2003-03-07 Paolo Carlini PR libstdc++/9182 * include/bits/fstream.tcc (_M_really_overflow): Check for _M_convert_to_external possible failures. * include/std/std_fstream.h (sync): Check _M_really_overflow return value and return -1 in case of failure. * testsuite/27_io/filebuf_virtuals.cc (test13, test14): Add. 2003-03-07 Paolo Carlini PR libstdc++/9826 * include/bits/istream.tcc (operator>>(_CharT*), operator>>(basic_string&), ws): Pass a char_type to __ctype.is. * testsuite/27_io/stringstream.cc (test02): Add. * include/bits/istream.tcc (operator>>(_CharT*)): Assign a char_type to *__s. From-SVN: r63953 --- libstdc++-v3/ChangeLog | 19 +++++++ libstdc++-v3/include/bits/fstream.tcc | 31 +++++----- libstdc++-v3/include/bits/istream.tcc | 8 +-- libstdc++-v3/include/std/std_fstream.h | 12 +++- .../testsuite/27_io/filebuf_virtuals.cc | 57 +++++++++++++++++++ libstdc++-v3/testsuite/27_io/stringstream.cc | 18 ++++++ 6 files changed, 125 insertions(+), 20 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 763b5739e51..5298239337a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,22 @@ +2003-03-07 Paolo Carlini + + PR libstdc++/9182 + * include/bits/fstream.tcc (_M_really_overflow): Check + for _M_convert_to_external possible failures. + * include/std/std_fstream.h (sync): Check _M_really_overflow + return value and return -1 in case of failure. + * testsuite/27_io/filebuf_virtuals.cc (test13, test14): Add. + +2003-03-07 Paolo Carlini + + PR libstdc++/9826 + * include/bits/istream.tcc (operator>>(_CharT*), + operator>>(basic_string&), ws): Pass a char_type to __ctype.is. + * testsuite/27_io/stringstream.cc (test02): Add. + + * include/bits/istream.tcc (operator>>(_CharT*)): + Assign a char_type to *__s. + 2003-03-07 Petur Runolfsson PR libstdc++/9817 diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index be4b0c02947..484ed7be057 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -362,26 +362,31 @@ namespace std this->_M_out_lim - this->_M_out_beg, __elen, __plen); - // Convert pending sequence to external representation, output. - // If eof, then just attempt sync. - if (!traits_type::eq_int_type(__c, traits_type::eof())) + // Checks for codecvt.out failures and _M_file.xsputn failures, + // respectively, inside _M_convert_to_external. + if (__testunbuffered || (__elen && __elen == __plen)) { - char_type __pending = traits_type::to_char_type(__c); - _M_convert_to_external(&__pending, 1, __elen, __plen); + // Convert pending sequence to external representation, output. + // If eof, then just attempt sync. + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + char_type __pending = traits_type::to_char_type(__c); + _M_convert_to_external(&__pending, 1, __elen, __plen); - // User code must flush when switching modes (thus don't sync). - if (__elen == __plen) + // User code must flush when switching modes (thus don't sync). + if (__elen == __plen && __elen) + { + _M_set_indeterminate(); + __ret = traits_type::not_eof(__c); + } + } + else if (!_M_file.sync()) { _M_set_indeterminate(); __ret = traits_type::not_eof(__c); } } - else if (!_M_file.sync()) - { - _M_set_indeterminate(); - __ret = traits_type::not_eof(__c); - } - } + } _M_last_overflowed = true; return __ret; } diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc index e0ae5ad8507..0bd7fff51da 100644 --- a/libstdc++-v3/include/bits/istream.tcc +++ b/libstdc++-v3/include/bits/istream.tcc @@ -1036,9 +1036,9 @@ namespace std while (__extracted < __num - 1 && !_Traits::eq_int_type(__c, __eof) - && !__ctype.is(ctype_base::space, __c)) + && !__ctype.is(ctype_base::space, _Traits::to_char_type(__c))) { - *__s++ = __c; + *__s++ = _Traits::to_char_type(__c); ++__extracted; __c = __sb->snextc(); } @@ -1081,7 +1081,7 @@ namespace std __int_type __c = __sb->sgetc(); while (!_Traits::eq_int_type(__c, __eof) - && __ctype.is(ctype_base::space, __c)) + && __ctype.is(ctype_base::space, _Traits::to_char_type(__c))) __c = __sb->snextc(); if (_Traits::eq_int_type(__c, __eof)) @@ -1119,7 +1119,7 @@ namespace std while (__extracted < __n && !_Traits::eq_int_type(__c, __eof) - && !__ctype.is(ctype_base::space, __c)) + && !__ctype.is(ctype_base::space, _Traits::to_char_type(__c))) { __str += _Traits::to_char_type(__c); ++__extracted; diff --git a/libstdc++-v3/include/std/std_fstream.h b/libstdc++-v3/include/std/std_fstream.h index 6dd75dd1bba..34b32a157c3 100644 --- a/libstdc++-v3/include/std/std_fstream.h +++ b/libstdc++-v3/include/std/std_fstream.h @@ -311,6 +311,7 @@ namespace std virtual int sync() { + int __ret = 0; bool __testput = this->_M_out_cur && this->_M_out_beg < this->_M_out_lim; @@ -320,14 +321,19 @@ namespace std { // Need to restore current position after the write. off_type __off = this->_M_out_cur - this->_M_out_lim; - _M_really_overflow(); // _M_file.sync() will be called within - if (__off) + + // _M_file.sync() will be called within + if (traits_type::eq_int_type(_M_really_overflow(), + traits_type::eof())) + __ret = -1; + else if (__off) _M_file.seekoff(__off, ios_base::cur); } else _M_file.sync(); + _M_last_overflowed = false; - return 0; + return __ret; } // [documentation is inherited] diff --git a/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc b/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc index 660abd1752a..fd459636049 100644 --- a/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc +++ b/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc @@ -74,6 +74,7 @@ const char name_03[] = "filebuf_virtuals-3.txt"; // empty file, need to create const char name_04[] = "filebuf_virtuals-4.txt"; // empty file, need to create const char name_05[] = "filebuf_virtuals-5.txt"; // empty file, need to create const char name_06[] = "filebuf_virtuals-6.txt"; // empty file, need to create +const char name_07[] = "filebuf_virtuals-7.txt"; // empty file, need to create class derived_filebuf: public std::filebuf { @@ -704,6 +705,60 @@ void test12() fbuf.close(); } +class errorcvt : public std::codecvt +{ +protected: + std::codecvt_base::result + do_out(mbstate_t&, const char* from, const char*, + const char*& from_next, char* to, char*, + char*& to_next) const + { + from_next = from; + to_next = to; + return std::codecvt::error; + } + + virtual bool do_always_noconv() const throw() + { + return false; + } +}; + +// libstdc++/9182 +void test13() +{ + using namespace std; + bool test = true; + + locale loc; + loc = locale(loc, new errorcvt); + + filebuf fbuf1; + fbuf1.pubimbue(loc); + fbuf1.open(name_07, ios_base::out | ios_base::trunc); + fbuf1.sputn("ison", 4); + int r = fbuf1.pubsync(); + VERIFY( r == -1 ); + fbuf1.close(); +} + +void test14() +{ + using namespace std; + bool test = true; + + locale loc; + loc = locale(loc, new errorcvt); + + filebuf fbuf1; + fbuf1.pubimbue(loc); + fbuf1.pubsetbuf(0, 0); + fbuf1.open(name_07, ios_base::out | ios_base::trunc); + streamsize n = fbuf1.sputn("onne", 4); + VERIFY( n == 0 ); + fbuf1.close(); +} + main() { test01(); @@ -720,5 +775,7 @@ main() test10(); test11(); test12(); + test13(); + test14(); return 0; } diff --git a/libstdc++-v3/testsuite/27_io/stringstream.cc b/libstdc++-v3/testsuite/27_io/stringstream.cc index 576b72d5282..a9778952d90 100644 --- a/libstdc++-v3/testsuite/27_io/stringstream.cc +++ b/libstdc++-v3/testsuite/27_io/stringstream.cc @@ -56,8 +56,26 @@ namespace test template class basic_stringstream >; } // test +// libstdc++/9826 +void test02() +{ + using namespace std; + using __gnu_cxx_test::pod_char; + + basic_stringstream > sstr; + // 1 + basic_string > str; + sstr >> str; + // 2 + pod_char* chr; + sstr >> chr; + // 3 + sstr >> ws; +} + int main() { test01(); + test02(); return 0; }