Commit b988dfc5 by Benjamin Kosnik Committed by Benjamin Kosnik

fstream.tcc (filebuf::seekpos): Fix.


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.

From-SVN: r52057
parent 973348ec
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> 2002-04-05 Jonathan Wakely <jw@kayari.org>
* include/bits/stl_algo.h (unique_copy, __gcd, rotate, rotate_copy, * include/bits/stl_algo.h (unique_copy, __gcd, rotate, rotate_copy,
......
...@@ -560,17 +560,17 @@ namespace std ...@@ -560,17 +560,17 @@ namespace std
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
{ {
pos_type __ret = pos_type(off_type(-1)); pos_type __ret = pos_type(off_type(-1));
bool __testopen = this->is_open(); bool __testin = _M_mode & ios_base::in;
bool __testin = __mode & ios_base::in && _M_mode & ios_base::in; bool __testout = _M_mode & ios_base::out;
bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
// Should probably do has_facet checks here. // Should probably do has_facet checks here.
int __width = use_facet<__codecvt_type>(_M_buf_locale).encoding(); int __width = use_facet<__codecvt_type>(_M_buf_locale).encoding();
if (__width < 0) if (__width < 0)
__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. // Ditch any pback buffers to avoid confusion.
_M_pback_destroy(); _M_pback_destroy();
...@@ -615,13 +615,10 @@ namespace std ...@@ -615,13 +615,10 @@ namespace std
basic_filebuf<_CharT, _Traits>:: basic_filebuf<_CharT, _Traits>::
seekpos(pos_type __pos, ios_base::openmode __mode) seekpos(pos_type __pos, ios_base::openmode __mode)
{ {
pos_type __ret; #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
off_type __off = __pos; // 171. Strange seekpos() semantics due to joint position
return this->seekoff(off_type(__pos), ios_base::beg, __mode);
__ret = this->seekoff(__off, ios_base::beg, __mode); #endif
_M_last_overflowed = false;
return __ret;
} }
template<typename _CharT, typename _Traits> template<typename _CharT, typename _Traits>
......
...@@ -419,9 +419,7 @@ namespace std ...@@ -419,9 +419,7 @@ namespace std
basic_ostream<_CharT, _Traits>::tellp() basic_ostream<_CharT, _Traits>::tellp()
{ {
pos_type __ret = pos_type(-1); pos_type __ret = pos_type(-1);
bool __testok = this->fail() != true; if (!this->fail())
if (__testok)
__ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
return __ret; return __ret;
} }
...@@ -431,9 +429,7 @@ namespace std ...@@ -431,9 +429,7 @@ namespace std
basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::seekp(pos_type __pos) basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
{ {
bool __testok = this->fail() != true; if (!this->fail())
if (__testok)
{ {
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 136. seekp, seekg setting wrong streams? // 136. seekp, seekg setting wrong streams?
...@@ -452,9 +448,7 @@ namespace std ...@@ -452,9 +448,7 @@ namespace std
basic_ostream<_CharT, _Traits>:: basic_ostream<_CharT, _Traits>::
seekp(off_type __off, ios_base::seekdir __d) seekp(off_type __off, ios_base::seekdir __d)
{ {
bool __testok = this->fail() != true; if (!this->fail())
if (__testok)
{ {
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 136. seekp, seekg setting wrong streams? // 136. seekp, seekg setting wrong streams?
......
...@@ -124,8 +124,10 @@ namespace std ...@@ -124,8 +124,10 @@ namespace std
bool __testin = __mode & ios_base::in && _M_mode & ios_base::in; bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
bool __testout = __mode & ios_base::out && _M_mode & ios_base::out; bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
bool __testboth = __testin && __testout && __way != ios_base::cur; bool __testboth = __testin && __testout && __way != ios_base::cur;
__testin &= !(__mode & ios_base::out);
if (_M_buf_size && ((__testin != __testout) || __testboth)) __testout &= !(__mode & ios_base::in);
if (_M_buf_size && (__testin || __testout || __testboth))
{ {
char_type* __beg = _M_buf; char_type* __beg = _M_buf;
char_type* __curi = NULL; char_type* __curi = NULL;
...@@ -133,12 +135,12 @@ namespace std ...@@ -133,12 +135,12 @@ namespace std
char_type* __endi = NULL; char_type* __endi = NULL;
char_type* __endo = NULL; char_type* __endo = NULL;
if (__testin) if (__testin || __testboth)
{ {
__curi = this->gptr(); __curi = this->gptr();
__endi = this->egptr(); __endi = this->egptr();
} }
if (__testout) if (__testout || __testboth)
{ {
__curo = this->pptr(); __curo = this->pptr();
__endo = this->epptr(); __endo = this->epptr();
...@@ -157,13 +159,13 @@ namespace std ...@@ -157,13 +159,13 @@ namespace std
__newoffo = __endo - __beg; __newoffo = __endo - __beg;
} }
if (__testin if ((__testin || __testboth)
&& __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off) && __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off)
{ {
_M_in_cur = __beg + __newoffi + __off; _M_in_cur = __beg + __newoffi + __off;
__ret = pos_type(__newoffi); __ret = pos_type(__newoffi);
} }
if (__testout if ((__testout || __testboth)
&& __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off) && __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off)
{ {
_M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg)); _M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg));
...@@ -179,33 +181,44 @@ namespace std ...@@ -179,33 +181,44 @@ namespace std
seekpos(pos_type __sp, ios_base::openmode __mode) seekpos(pos_type __sp, ios_base::openmode __mode)
{ {
pos_type __ret = pos_type(off_type(-1)); 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) if (_M_buf_size)
{
__beg = this->eback();
__end = this->egptr();
}
if (__testout)
{
__beg = this->pbase();
__end = _M_buf + _M_buf_size;
}
if (0 <= __pos && __pos <= __end - __beg)
{ {
// Need to set both of these if applicable off_type __pos = __sp._M_position();
if (__testin) char_type* __beg = NULL;
_M_in_cur = _M_in_beg + __pos; char_type* __end = NULL;
if (__testout) bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
_M_out_cur_move((__pos) - (_M_out_cur - __beg)); bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
__ret = pos_type(off_type(__pos)); 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; return __ret;
} }
......
...@@ -306,7 +306,7 @@ namespace std ...@@ -306,7 +306,7 @@ namespace std
void void
open(const char* __s, ios_base::openmode __mode = ios_base::in) 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); this->setstate(ios_base::failbit);
} }
......
// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com> // 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 // 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 // software; you can redistribute it and/or modify it under the
...@@ -38,9 +38,50 @@ void test01() ...@@ -38,9 +38,50 @@ void test01()
VERIFY( std::strncmp(strlit, buf, strlitsize) != 0 ); 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() int main()
{ {
using namespace std;
test01(); 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; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment