re PR fortran/60956 (error reading (and writing) large text files in gfortran)
2015-02-07 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/60956 * io/fbuf.c (fbuf_flush_list): New function that only flushes if current fbuf position exceeds a limit. * io/fbuf.h: Declare the new function. * io/io.h (enum unit_mode): Add two new modes. * io/list_read.c (list_formatted_read_scalar): Call new function. * io/write.c: Include fbuf.h. (list_formatted_write_scalar): Call new function. From-SVN: r220505
This commit is contained in:
parent
c0c91386b7
commit
1060d9404d
6 changed files with 54 additions and 1 deletions
|
@ -1,3 +1,14 @@
|
|||
2015-02-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||
|
||||
PR libgfortran/60956
|
||||
* io/fbuf.c (fbuf_flush_list): New function that only flushes
|
||||
if current fbuf position exceeds a limit.
|
||||
* io/fbuf.h: Declare the new function.
|
||||
* io/io.h (enum unit_mode): Add two new modes.
|
||||
* io/list_read.c (list_formatted_read_scalar): Call new function.
|
||||
* io/write.c: Include fbuf.h. (list_formatted_write_scalar):
|
||||
Call new function.
|
||||
|
||||
2015-01-24 Janne Blomqvist <jb@gcc.gnu.org>
|
||||
|
||||
PR libfortran/64770
|
||||
|
|
|
@ -171,6 +171,42 @@ fbuf_flush (gfc_unit * u, unit_mode mode)
|
|||
}
|
||||
|
||||
|
||||
/* The mode argument is LIST_WRITING for write mode and LIST_READING for
|
||||
read. This should only be used for list directed I/O.
|
||||
Return value is 0 for success, -1 on failure. */
|
||||
|
||||
int
|
||||
fbuf_flush_list (gfc_unit * u, unit_mode mode)
|
||||
{
|
||||
int nwritten;
|
||||
|
||||
if (!u->fbuf)
|
||||
return 0;
|
||||
|
||||
if (u->fbuf->pos < 524288) /* Upper limit for list writing. */
|
||||
return 0;
|
||||
|
||||
fbuf_debug (u, "fbuf_flush_list with mode %d: ", mode);
|
||||
|
||||
if (mode == LIST_WRITING)
|
||||
{
|
||||
nwritten = swrite (u->s, u->fbuf->buf, u->fbuf->pos);
|
||||
if (nwritten < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Salvage remaining bytes for both reading and writing. */
|
||||
if (u->fbuf->act > u->fbuf->pos)
|
||||
memmove (u->fbuf->buf, u->fbuf->buf + u->fbuf->pos,
|
||||
u->fbuf->act - u->fbuf->pos);
|
||||
|
||||
u->fbuf->act -= u->fbuf->pos;
|
||||
u->fbuf->pos = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fbuf_seek (gfc_unit * u, int off, int whence)
|
||||
{
|
||||
|
|
|
@ -59,6 +59,9 @@ internal_proto(fbuf_alloc);
|
|||
extern int fbuf_flush (gfc_unit *, unit_mode);
|
||||
internal_proto(fbuf_flush);
|
||||
|
||||
extern int fbuf_flush_list (gfc_unit *, unit_mode);
|
||||
internal_proto(fbuf_flush_list);
|
||||
|
||||
extern int fbuf_seek (gfc_unit *, int, int);
|
||||
internal_proto(fbuf_seek);
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ typedef enum
|
|||
unit_advance;
|
||||
|
||||
typedef enum
|
||||
{READING, WRITING}
|
||||
{READING, WRITING, LIST_READING, LIST_WRITING}
|
||||
unit_mode;
|
||||
|
||||
typedef enum
|
||||
|
|
|
@ -2210,6 +2210,7 @@ cleanup:
|
|||
free_line (dtp);
|
||||
hit_eof (dtp);
|
||||
}
|
||||
fbuf_flush_list (dtp->u.p.current_unit, LIST_READING);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "io.h"
|
||||
#include "fbuf.h"
|
||||
#include "format.h"
|
||||
#include "unix.h"
|
||||
#include <assert.h>
|
||||
|
@ -1585,6 +1586,7 @@ list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
|
|||
internal_error (&dtp->common, "list_formatted_write(): Bad type");
|
||||
}
|
||||
|
||||
fbuf_flush_list (dtp->u.p.current_unit, LIST_WRITING);
|
||||
dtp->u.p.char_flag = (type == BT_CHARACTER);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue