From 1060d9404d1ab275b540efe1c7868d08c07a81e1 Mon Sep 17 00:00:00 2001 From: Jerry DeLisle Date: Sat, 7 Feb 2015 15:13:15 +0000 Subject: re PR fortran/60956 (error reading (and writing) large text files in gfortran) 2015-02-07 Jerry DeLisle 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 --- libgfortran/io/fbuf.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'libgfortran/io/fbuf.c') diff --git a/libgfortran/io/fbuf.c b/libgfortran/io/fbuf.c index 9a3a486..b3750d2 100644 --- a/libgfortran/io/fbuf.c +++ b/libgfortran/io/fbuf.c @@ -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) { -- cgit v1.1