]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/60956 (error reading (and writing) large text files in gfortran)
authorJerry DeLisle <jvdelisle@gcc.gnu.org>
Mon, 23 Mar 2015 01:32:15 +0000 (01:32 +0000)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Mon, 23 Mar 2015 01:32:15 +0000 (01:32 +0000)
2015-03-22  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

PR libgfortran/60956
Backport from mainline
* 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: r221584

libgfortran/ChangeLog
libgfortran/io/fbuf.c
libgfortran/io/fbuf.h
libgfortran/io/io.h
libgfortran/io/list_read.c
libgfortran/io/write.c

index bfa4927652f790375c4509fdcd6b3886cad4f826..547a7f29229c6f7c043a5f01b23e970e940bbd48 100644 (file)
@@ -1,3 +1,15 @@
+2015-03-22  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
+
+       PR libgfortran/60956
+       Backport from mainline
+       * 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.
+
 2014-12-19  Release Manager
 
        * GCC 4.8.4 released.
index ace990db821b2383d6e8c9bce2b153c54d820e61..4d48cc9fb404c8f7ea2e33039bedc2f09fff7e1d 100644 (file)
@@ -174,6 +174,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)
 {
index d125a2cf6e1a005a4620e4baa1a79083443adeea..64cf0430fad79c50088a929d88ba4ef9acc6b4d1 100644 (file)
@@ -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);
 
index 10f09855f1f8f6388033bdae495f7ab3d3f24ad5..e78f3151bbde326e9acaa73e0ce99f2826d38de2 100644 (file)
@@ -201,7 +201,7 @@ typedef enum
 unit_advance;
 
 typedef enum
-{READING, WRITING}
+{READING, WRITING, LIST_READING, LIST_WRITING}
 unit_mode;
 
 typedef enum
index 3c766d7c780a7779a0bc934c026d450c8749b4ae..2b80838fc9fed4c1b0eb83986a6cad771a8e98d8 100644 (file)
@@ -2001,6 +2001,7 @@ cleanup:
       free_line (dtp);
       hit_eof (dtp);
     }
+  fbuf_flush_list (dtp->u.p.current_unit, LIST_READING);
   return err;
 }
 
index a3c78ce7c6f9f186f13ff2d1228e59a8befdb45e..4ef5586a657b4bf647505e9762abb9aa5c5724aa 100644 (file)
@@ -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>
@@ -1577,6 +1578,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);
 }