aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/io/fbuf.c
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2015-02-07 15:13:15 +0000
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2015-02-07 15:13:15 +0000
commit1060d9404d1ab275b540efe1c7868d08c07a81e1 (patch)
tree81fec064d6dc7d20671ba02ca25c864dc9cec2f8 /libgfortran/io/fbuf.c
parentc0c91386b7ebd2c241d6ee2d5c172e57f5185472 (diff)
downloadgcc-1060d9404d1ab275b540efe1c7868d08c07a81e1.zip
gcc-1060d9404d1ab275b540efe1c7868d08c07a81e1.tar.gz
gcc-1060d9404d1ab275b540efe1c7868d08c07a81e1.tar.bz2
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
Diffstat (limited to 'libgfortran/io/fbuf.c')
-rw-r--r--libgfortran/io/fbuf.c36
1 files changed, 36 insertions, 0 deletions
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)
{