summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2002-04-09 06:14:32 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2002-04-09 06:14:32 +0000
commitefd81e8d250edfd29de611895051b106df3b7369 (patch)
treed736fe8e961fce328e0ed710bb828c3c517c9a3d /libstdc++-v3
parent17f8f188580b675aee94757102c12f958e9759df (diff)
downloadgcc-efd81e8d250edfd29de611895051b106df3b7369.tar.gz
2002-04-08 Benjamin Kosnik <bkoz@redhat.com>
libstdc++/5180 * include/bits/fstream.tcc (filebuf::seekpos): Fix. * include/std/std_fstream.h: Clean. * include/bits/ostream.tcc: Remove extraneous variables. * include/bits/sstream.tcc (stringbuf::seekoff): Be strict about open modes and which modes. (stringbuf::seekpos): Same. * testsuite/27_io/stringbuf_virtuals.cc: New tests. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52057 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog11
-rw-r--r--libstdc++-v3/include/bits/fstream.tcc21
-rw-r--r--libstdc++-v3/include/bits/ostream.tcc12
-rw-r--r--libstdc++-v3/include/bits/sstream.tcc73
-rw-r--r--libstdc++-v3/include/std/std_fstream.h2
-rw-r--r--libstdc++-v3/testsuite/27_io/stringbuf_virtuals.cc43
6 files changed, 109 insertions, 53 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 97de30d917d..64e40fae669 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+2002-04-08 Benjamin Kosnik <bkoz@redhat.com>
+
+ libstdc++/5180
+ * include/bits/fstream.tcc (filebuf::seekpos): Fix.
+ * include/std/std_fstream.h: Clean.
+ * include/bits/ostream.tcc: Remove extraneous variables.
+ * include/bits/sstream.tcc (stringbuf::seekoff): Be strict about
+ open modes and which modes.
+ (stringbuf::seekpos): Same.
+ * testsuite/27_io/stringbuf_virtuals.cc: New tests.
+
2002-04-05 Jonathan Wakely <jw@kayari.org>
* include/bits/stl_algo.h (unique_copy, __gcd, rotate, rotate_copy,
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index 0d0882619e8..0117d57fc4c 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -560,17 +560,17 @@ namespace std
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
{
pos_type __ret = pos_type(off_type(-1));
- bool __testopen = this->is_open();
- bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
- bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
+ bool __testin = _M_mode & ios_base::in;
+ bool __testout = _M_mode & ios_base::out;
// Should probably do has_facet checks here.
int __width = use_facet<__codecvt_type>(_M_buf_locale).encoding();
if (__width < 0)
__width = 0;
- bool __testfail = __off != 0 && __width <= 0;
+ bool __testfail = __off != 0 && __width <= 0;
- if (__testopen && !__testfail && (__testin || __testout))
+ if (this->is_open() && !__testfail
+ && __mode & _M_mode && (__testin || __testout))
{
// Ditch any pback buffers to avoid confusion.
_M_pback_destroy();
@@ -615,13 +615,10 @@ namespace std
basic_filebuf<_CharT, _Traits>::
seekpos(pos_type __pos, ios_base::openmode __mode)
{
- pos_type __ret;
- off_type __off = __pos;
-
- __ret = this->seekoff(__off, ios_base::beg, __mode);
-
- _M_last_overflowed = false;
- return __ret;
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+// 171. Strange seekpos() semantics due to joint position
+ return this->seekoff(off_type(__pos), ios_base::beg, __mode);
+#endif
}
template<typename _CharT, typename _Traits>
diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc
index 785df851ec1..5c4799b9caa 100644
--- a/libstdc++-v3/include/bits/ostream.tcc
+++ b/libstdc++-v3/include/bits/ostream.tcc
@@ -419,9 +419,7 @@ namespace std
basic_ostream<_CharT, _Traits>::tellp()
{
pos_type __ret = pos_type(-1);
- bool __testok = this->fail() != true;
-
- if (__testok)
+ if (!this->fail())
__ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
return __ret;
}
@@ -431,9 +429,7 @@ namespace std
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
{
- bool __testok = this->fail() != true;
-
- if (__testok)
+ if (!this->fail())
{
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 136. seekp, seekg setting wrong streams?
@@ -452,9 +448,7 @@ namespace std
basic_ostream<_CharT, _Traits>::
seekp(off_type __off, ios_base::seekdir __d)
{
- bool __testok = this->fail() != true;
-
- if (__testok)
+ if (!this->fail())
{
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 136. seekp, seekg setting wrong streams?
diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc
index f83bb697dcc..6aec6e8558a 100644
--- a/libstdc++-v3/include/bits/sstream.tcc
+++ b/libstdc++-v3/include/bits/sstream.tcc
@@ -124,8 +124,10 @@ namespace std
bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
bool __testboth = __testin && __testout && __way != ios_base::cur;
-
- if (_M_buf_size && ((__testin != __testout) || __testboth))
+ __testin &= !(__mode & ios_base::out);
+ __testout &= !(__mode & ios_base::in);
+
+ if (_M_buf_size && (__testin || __testout || __testboth))
{
char_type* __beg = _M_buf;
char_type* __curi = NULL;
@@ -133,12 +135,12 @@ namespace std
char_type* __endi = NULL;
char_type* __endo = NULL;
- if (__testin)
+ if (__testin || __testboth)
{
__curi = this->gptr();
__endi = this->egptr();
}
- if (__testout)
+ if (__testout || __testboth)
{
__curo = this->pptr();
__endo = this->epptr();
@@ -157,13 +159,13 @@ namespace std
__newoffo = __endo - __beg;
}
- if (__testin
+ if ((__testin || __testboth)
&& __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off)
{
_M_in_cur = __beg + __newoffi + __off;
__ret = pos_type(__newoffi);
}
- if (__testout
+ if ((__testout || __testboth)
&& __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off)
{
_M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg));
@@ -179,33 +181,44 @@ namespace std
seekpos(pos_type __sp, ios_base::openmode __mode)
{
pos_type __ret = pos_type(off_type(-1));
- off_type __pos = __sp._M_position();
- char_type* __beg = NULL;
- char_type* __end = NULL;
- bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
- bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
- if (__testin)
- {
- __beg = this->eback();
- __end = this->egptr();
- }
- if (__testout)
- {
- __beg = this->pbase();
- __end = _M_buf + _M_buf_size;
- }
-
- if (0 <= __pos && __pos <= __end - __beg)
+ if (_M_buf_size)
{
- // Need to set both of these if applicable
- if (__testin)
- _M_in_cur = _M_in_beg + __pos;
- if (__testout)
- _M_out_cur_move((__pos) - (_M_out_cur - __beg));
- __ret = pos_type(off_type(__pos));
+ off_type __pos = __sp._M_position();
+ char_type* __beg = NULL;
+ char_type* __end = NULL;
+ bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
+ bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
+ bool __testboth = __testin && __testout;
+ __testin &= !(__mode & ios_base::out);
+ __testout &= !(__mode & ios_base::in);
+
+ // NB: Ordered.
+ bool __testposi = false;
+ bool __testposo = false;
+ if (__testin || __testboth)
+ {
+ __beg = this->eback();
+ __end = this->egptr();
+ if (0 <= __pos && __pos <= __end - __beg)
+ __testposi = true;
+ }
+ if (__testout || __testboth)
+ {
+ __beg = this->pbase();
+ __end = _M_buf + _M_buf_size;
+ if (0 <= __pos && __pos <= __end - __beg)
+ __testposo = true;
+ }
+ if (__testposi || __testposo)
+ {
+ if (__testposi)
+ _M_in_cur = _M_in_beg + __pos;
+ if (__testposo)
+ _M_out_cur_move((__pos) - (_M_out_cur - __beg));
+ __ret = pos_type(off_type(__pos));
+ }
}
-
return __ret;
}
diff --git a/libstdc++-v3/include/std/std_fstream.h b/libstdc++-v3/include/std/std_fstream.h
index c3273b55fd4..c462e7bd188 100644
--- a/libstdc++-v3/include/std/std_fstream.h
+++ b/libstdc++-v3/include/std/std_fstream.h
@@ -306,7 +306,7 @@ namespace std
void
open(const char* __s, ios_base::openmode __mode = ios_base::in)
{
- if (_M_filebuf.open(__s, __mode | ios_base::in) == NULL)
+ if (!_M_filebuf.open(__s, __mode | ios_base::in))
this->setstate(ios_base::failbit);
}
diff --git a/libstdc++-v3/testsuite/27_io/stringbuf_virtuals.cc b/libstdc++-v3/testsuite/27_io/stringbuf_virtuals.cc
index 7e20164712a..318bb72fa8a 100644
--- a/libstdc++-v3/testsuite/27_io/stringbuf_virtuals.cc
+++ b/libstdc++-v3/testsuite/27_io/stringbuf_virtuals.cc
@@ -1,6 +1,6 @@
// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -38,9 +38,50 @@ void test01()
VERIFY( std::strncmp(strlit, buf, strlitsize) != 0 );
}
+void test02(std::stringbuf& in, bool pass)
+{
+ using namespace std;
+ typedef streambuf::pos_type pos_type;
+ typedef streambuf::off_type off_type;
+ pos_type bad = pos_type(off_type(-1));
+ pos_type p = 0;
+
+ // seekoff
+ p = in.pubseekoff(0, ios_base::beg, ios_base::in);
+ if (pass)
+ VERIFY( p != bad );
+
+ p = in.pubseekoff(0, ios_base::beg, ios_base::out);
+ VERIFY( p == bad );
+
+ p = in.pubseekoff(0, ios_base::beg);
+ VERIFY( p == bad );
+
+
+ // seekpos
+ p = in.pubseekpos(0, ios_base::in);
+ if (pass)
+ VERIFY( p != bad );
+
+ p = in.pubseekpos(0, ios_base::out);
+ VERIFY( p == bad );
+
+ p = in.pubseekpos(0);
+ VERIFY( p == bad );
+}
+
int main()
{
+ using namespace std;
test01();
+ // movie star, submarine scientist!
+ stringbuf in1("Hedy Lamarr", ios_base::in);
+ stringbuf in2(ios_base::in);
+ stringbuf in3("", ios_base::in);
+ test02(in1, true);
+ test02(in2, false);
+ test02(in3, false);
+
return 0;
}