diff options
author | jvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-02-07 15:13:15 +0000 |
---|---|---|
committer | jvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-02-07 15:13:15 +0000 |
commit | cf8796efecc4d7d7de6d01a78928c05dc9b5496a (patch) | |
tree | 81fec064d6dc7d20671ba02ca25c864dc9cec2f8 /libgfortran | |
parent | 3622a8485ed1ffbcbdaf4e9a768c2b142b9726e4 (diff) | |
download | gcc-cf8796efecc4d7d7de6d01a78928c05dc9b5496a.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@220505 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran')
-rw-r--r-- | libgfortran/ChangeLog | 11 | ||||
-rw-r--r-- | libgfortran/io/fbuf.c | 36 | ||||
-rw-r--r-- | libgfortran/io/fbuf.h | 3 | ||||
-rw-r--r-- | libgfortran/io/io.h | 2 | ||||
-rw-r--r-- | libgfortran/io/list_read.c | 1 | ||||
-rw-r--r-- | libgfortran/io/write.c | 2 |
6 files changed, 54 insertions, 1 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index e228a677105..d3b8f8f6e48 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -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 diff --git a/libgfortran/io/fbuf.c b/libgfortran/io/fbuf.c index 9a3a486fe40..b3750d21a3b 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) { diff --git a/libgfortran/io/fbuf.h b/libgfortran/io/fbuf.h index 902cd6ef869..220c8d7b56d 100644 --- a/libgfortran/io/fbuf.h +++ b/libgfortran/io/fbuf.h @@ -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); diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 928123bff34..f34d0c34cf6 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -231,7 +231,7 @@ typedef enum unit_advance; typedef enum -{READING, WRITING} +{READING, WRITING, LIST_READING, LIST_WRITING} unit_mode; typedef enum diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index 640774b2ac1..45243ed9f39 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -2210,6 +2210,7 @@ cleanup: free_line (dtp); hit_eof (dtp); } + fbuf_flush_list (dtp->u.p.current_unit, LIST_READING); return err; } diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c index 2149456d3da..3e890b981d1 100644 --- a/libgfortran/io/write.c +++ b/libgfortran/io/write.c @@ -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); } |