mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-07 14:57:21 +08:00
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
This commit is contained in:
parent
973348ec02
commit
b988dfc58f
@ -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,
|
||||
|
@ -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>
|
||||
|
@ -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?
|
||||
|
@ -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)
|
||||
if (_M_buf_size)
|
||||
{
|
||||
__beg = this->eback();
|
||||
__end = this->egptr();
|
||||
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));
|
||||
}
|
||||
}
|
||||
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
|
||||
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));
|
||||
}
|
||||
|
||||
return __ret;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user