re PR libstdc++/9182 (basic_filebuf<> does not report errors in codecvt<>::out)

2003-03-07  Paolo Carlini  <pcarlini@unitus.it>

	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  <pcarlini@unitus.it>

	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
This commit is contained in:
Paolo Carlini 2003-03-07 23:06:28 +01:00 committed by Paolo Carlini
parent 50aac998d4
commit 1deba98bd2
6 changed files with 125 additions and 20 deletions

View File

@ -1,3 +1,22 @@
2003-03-07 Paolo Carlini <pcarlini@unitus.it>
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 <pcarlini@unitus.it>
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 <peturr02@ru.is>
PR libstdc++/9817

View File

@ -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;
}

View File

@ -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;

View File

@ -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]

View File

@ -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<char, char, mbstate_t>
{
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<char, char, mbstate_t>::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;
}

View File

@ -56,8 +56,26 @@ namespace test
template class basic_stringstream<pod_char, char_traits<pod_char> >;
} // test
// libstdc++/9826
void test02()
{
using namespace std;
using __gnu_cxx_test::pod_char;
basic_stringstream<pod_char, char_traits<pod_char> > sstr;
// 1
basic_string<pod_char, char_traits<pod_char> > str;
sstr >> str;
// 2
pod_char* chr;
sstr >> chr;
// 3
sstr >> ws;
}
int main()
{
test01();
test02();
return 0;
}