aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@unitus.it>2003-03-07 23:06:28 +0100
committerPaolo Carlini <paolo@gcc.gnu.org>2003-03-07 22:06:28 +0000
commit1deba98bd23b18dbaf4da0e42ee3d5d6c48fe758 (patch)
tree3af598b249b9920d009caed9e0797f741dabbc00
parent50aac998d41d566b358f8421c5e55188435422d7 (diff)
downloadgcc-1deba98bd23b18dbaf4da0e42ee3d5d6c48fe758.zip
gcc-1deba98bd23b18dbaf4da0e42ee3d5d6c48fe758.tar.gz
gcc-1deba98bd23b18dbaf4da0e42ee3d5d6c48fe758.tar.bz2
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
-rw-r--r--libstdc++-v3/ChangeLog19
-rw-r--r--libstdc++-v3/include/bits/fstream.tcc31
-rw-r--r--libstdc++-v3/include/bits/istream.tcc8
-rw-r--r--libstdc++-v3/include/std/std_fstream.h12
-rw-r--r--libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc57
-rw-r--r--libstdc++-v3/testsuite/27_io/stringstream.cc18
6 files changed, 125 insertions, 20 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 763b573..5298239 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index be4b0c0..484ed7b 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 e0ae5ad..0bd7fff 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 6dd75dd..34b32a1 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 660abd1..fd45963 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<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;
}
diff --git a/libstdc++-v3/testsuite/27_io/stringstream.cc b/libstdc++-v3/testsuite/27_io/stringstream.cc
index 576b72d..a977895 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<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;
}