mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-02 08:13:58 +08:00
re PR libstdc++/12875 (Weird behaviour in basic_filebuf::setbuf())
2003-11-11 Paolo Carlini <pcarlini@suse.de> PR libstdc++/12875 * include/bits/fstream.tcc (setbuf): Don't do anything after open(), in particular don't discard data. (_M_allocate_internal_buffer): Tweak to not allocate memory in case the buffer is provided by the user via setbuf. * include/ext/stdio_filebuf.h: Tweak comment. * testsuite/27_io/basic_filebuf/setbuf/char/12875-1.cc: New. * testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc: Likewise. * testsuite/27_io/basic_filebuf/setbuf/char/2.cc: Tweak, now setbuf does nothing after open(). * testsuite/27_io/basic_filebuf/setbuf/char/3.cc: Likewise. From-SVN: r73477
This commit is contained in:
parent
a5966c9ef9
commit
dfad48c6e8
@ -1,3 +1,17 @@
|
||||
2003-11-11 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
PR libstdc++/12875
|
||||
* include/bits/fstream.tcc (setbuf): Don't do anything
|
||||
after open(), in particular don't discard data.
|
||||
(_M_allocate_internal_buffer): Tweak to not allocate memory
|
||||
in case the buffer is provided by the user via setbuf.
|
||||
* include/ext/stdio_filebuf.h: Tweak comment.
|
||||
* testsuite/27_io/basic_filebuf/setbuf/char/12875-1.cc: New.
|
||||
* testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc: Likewise.
|
||||
* testsuite/27_io/basic_filebuf/setbuf/char/2.cc: Tweak, now
|
||||
setbuf does nothing after open().
|
||||
* testsuite/27_io/basic_filebuf/setbuf/char/3.cc: Likewise.
|
||||
|
||||
2003-11-11 Doug Gregor <gregod@cs.rpi.edu>
|
||||
|
||||
* docs/html/debug.html: Document libstdc++ debug mode.
|
||||
|
@ -44,15 +44,15 @@ namespace std
|
||||
basic_filebuf<_CharT, _Traits>::
|
||||
_M_allocate_internal_buffer()
|
||||
{
|
||||
if (!_M_buf_allocated && this->_M_buf_size)
|
||||
// Allocate internal buffer only if one doesn't already exist
|
||||
// (either allocated or provided by the user via setbuf).
|
||||
if (!_M_buf_allocated && !this->_M_buf)
|
||||
{
|
||||
// Allocate internal buffer.
|
||||
this->_M_buf = new char_type[this->_M_buf_size];
|
||||
_M_buf_allocated = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Both close and setbuf need to deallocate internal buffers, if it exists.
|
||||
template<typename _CharT, typename _Traits>
|
||||
void
|
||||
basic_filebuf<_CharT, _Traits>::
|
||||
@ -213,8 +213,8 @@ namespace std
|
||||
else
|
||||
{
|
||||
// Worst-case number of external bytes.
|
||||
// XXX Not done encoding() == -1.
|
||||
const int __enc = _M_codecvt->encoding();
|
||||
// XXX Not done encoding() == -1.
|
||||
const int __enc = _M_codecvt->encoding();
|
||||
streamsize __blen; // Minimum buffer size.
|
||||
streamsize __rlen; // Number of chars to read.
|
||||
if (__enc > 0)
|
||||
@ -539,29 +539,22 @@ namespace std
|
||||
basic_filebuf<_CharT, _Traits>::
|
||||
setbuf(char_type* __s, streamsize __n)
|
||||
{
|
||||
if (!this->is_open() && __s == 0 && __n == 0)
|
||||
this->_M_buf_size = 1;
|
||||
else if (__s && __n > 0)
|
||||
{
|
||||
// This is implementation-defined behavior, and assumes that
|
||||
// an external char_type array of length __n exists and has
|
||||
// been pre-allocated. If this is not the case, things will
|
||||
// quickly blow up. When __n > 1, __n - 1 positions will be
|
||||
// used for the get area, __n - 1 for the put area and 1
|
||||
// position to host the overflow char of a full put area.
|
||||
// When __n == 1, 1 position will be used for the get area
|
||||
// and 0 for the put area, as in the unbuffered case above.
|
||||
|
||||
// Step 1: Destroy the current internal array.
|
||||
_M_destroy_internal_buffer();
|
||||
|
||||
// Step 2: Use the external array.
|
||||
this->_M_buf = __s;
|
||||
this->_M_buf_size = __n;
|
||||
_M_reading = false;
|
||||
_M_writing = false;
|
||||
_M_set_buffer(-1);
|
||||
}
|
||||
if (!this->is_open())
|
||||
if (__s == 0 && __n == 0)
|
||||
this->_M_buf_size = 1;
|
||||
else if (__s && __n > 0)
|
||||
{
|
||||
// This is implementation-defined behavior, and assumes that
|
||||
// an external char_type array of length __n exists and has
|
||||
// been pre-allocated. If this is not the case, things will
|
||||
// quickly blow up. When __n > 1, __n - 1 positions will be
|
||||
// used for the get area, __n - 1 for the put area and 1
|
||||
// position to host the overflow char of a full put area.
|
||||
// When __n == 1, 1 position will be used for the get area
|
||||
// and 0 for the put area, as in the unbuffered case above.
|
||||
this->_M_buf = __s;
|
||||
this->_M_buf_size = __n;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -66,9 +66,7 @@ namespace __gnu_cxx
|
||||
* @param fd An open file descriptor.
|
||||
* @param mode Same meaning as in a standard filebuf.
|
||||
* @param del Whether to close the file on destruction.
|
||||
* @param size Optimal or preferred size of internal buffer, in bytes.
|
||||
* Note that it includes a position for the overflow char,
|
||||
* therefore, can't be smaller than 2.
|
||||
* @param size Optimal or preferred size of internal buffer, in chars.
|
||||
*
|
||||
* This constructor associates a file stream buffer with an open
|
||||
* POSIX file descriptor. Iff @a del is true, then the associated
|
||||
@ -80,10 +78,8 @@ namespace __gnu_cxx
|
||||
/**
|
||||
* @param f An open @c FILE*.
|
||||
* @param mode Same meaning as in a standard filebuf.
|
||||
* @param size Optimal or preferred size of internal buffer, in bytes.
|
||||
* Defaults to system's @c BUFSIZ. Note that it includes
|
||||
* a position for the overflow char, therefore, can't be
|
||||
* smaller than 2.
|
||||
* @param size Optimal or preferred size of internal buffer, in chars.
|
||||
* Defaults to system's @c BUFSIZ.
|
||||
*
|
||||
* This constructor associates a file stream buffer with an open
|
||||
* C @c FILE*. The @c FILE* will not be automatically closed when the
|
||||
|
@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2003 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 27.8.1.4 Overridden virtual functions
|
||||
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// libstdc++/12875
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
const char* name = "tmp_setbuf4";
|
||||
static char buf[1024];
|
||||
|
||||
FILE* out = fopen(name, "w");
|
||||
fputs("Hello, world", out);
|
||||
fclose(out);
|
||||
|
||||
filebuf in;
|
||||
in.open(name, ios_base::in);
|
||||
char str[256];
|
||||
streamsize r = in.sgetn(str, 6);
|
||||
VERIFY( r == 6 );
|
||||
VERIFY( !memcmp(str, "Hello,", 6) );
|
||||
in.pubsetbuf(buf, 1024);
|
||||
r = in.sgetn(str, 6);
|
||||
VERIFY( r == 6 );
|
||||
VERIFY( !memcmp(str, " world", 6) );
|
||||
in.close();
|
||||
}
|
||||
|
||||
// libstdc++/12875
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2003 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
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// 27.8.1.4 Overridden virtual functions
|
||||
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// libstdc++/12875
|
||||
void test02()
|
||||
{
|
||||
using namespace std;
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
const char* name = "tmp_setbuf5";
|
||||
static char buf[1024];
|
||||
|
||||
filebuf out;
|
||||
out.open(name, ios_base::out);
|
||||
streamsize r = out.sputn("Hello,", 6);
|
||||
VERIFY( r == 6 );
|
||||
out.pubsetbuf(buf, 1024);
|
||||
r = out.sputn(" world", 6);
|
||||
VERIFY( r == 6 );
|
||||
VERIFY( out.close() );
|
||||
|
||||
FILE* in = fopen(name, "r");
|
||||
char str[256];
|
||||
fgets(str, 256, in);
|
||||
VERIFY( !strcmp(str, "Hello, world") );
|
||||
fclose(in);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test02();
|
||||
return 0;
|
||||
}
|
@ -32,8 +32,8 @@ void test01()
|
||||
const char* strlit = "how to tell a story and other essays: mark twain";
|
||||
const size_t strlitsize = std::strlen(strlit);
|
||||
filebuf fbuf;
|
||||
fbuf.open("tmp_setbuf2", ios_base::out);
|
||||
fbuf.pubsetbuf(buf, 512);
|
||||
fbuf.open("tmp_setbuf2", ios_base::out);
|
||||
fbuf.sputn(strlit, strlitsize);
|
||||
VERIFY( std::strncmp(strlit, buf, strlitsize) == 0 );
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <fstream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void test02()
|
||||
void test03()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
@ -32,17 +32,17 @@ void test02()
|
||||
const char* strlit = "how to tell a story and other essays: mark twain";
|
||||
const size_t strlitsize = std::strlen(strlit);
|
||||
filebuf fbuf01;
|
||||
fbuf01.open("tmp", ios_base::out);
|
||||
|
||||
// NB: +2 otherwise sputn is optimized to a direct write,
|
||||
// bypassing the buffer.
|
||||
fbuf01.pubsetbuf(buf, strlitsize + 2);
|
||||
fbuf01.open("tmp_setbuf3", ios_base::out);
|
||||
|
||||
fbuf01.sputn(strlit, strlitsize);
|
||||
VERIFY( std::strncmp(strlit, buf, strlitsize) == 0 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test02();
|
||||
test03();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user