From: Benjamin Kosnik Date: Tue, 9 Apr 2002 06:14:32 +0000 (+0000) Subject: fstream.tcc (filebuf::seekpos): Fix. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b988dfc58f3ebc62f92fe2678900cc13ae02edea;p=gcc.git fstream.tcc (filebuf::seekpos): Fix. 2002-04-08 Benjamin Kosnik 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. From-SVN: r52057 --- 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 + + 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 * 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 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 -// 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; }