re PR libfortran/16597 (gfortran: bug in unformatted I/O on scratch files)
authorBud Davis <bdavis9659@comcast.net>
Fri, 27 Aug 2004 07:59:30 +0000 (07:59 +0000)
committerBud Davis <bdavis@gcc.gnu.org>
Fri, 27 Aug 2004 07:59:30 +0000 (07:59 +0000)
2004-08-27  Bud Davis  <bdavis9659@comcast.net>

        PR fortran/16597
        * io/io.h: created typedef for unit_mode.
        * io/io.h (gfc_unit): added mode to unit structure.
        * io/transfer.c (data_transfer_init): flush if a write then
        read is done on a unit (direct access files).
        * io/rewind.c (st_rewind): Used unit mode instead of global.

        * gfortran.dg/pr16597.f90: New test.

From-SVN: r86654

gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr16597.f90 [new file with mode: 0644]
libgfortran/ChangeLog
libgfortran/io/io.h
libgfortran/io/rewind.c
libgfortran/io/transfer.c

index 9b73b6dea53a30c6211432b56c7e24cbcb6a0a9a..18f803758a67f3be07661a2aaffd686866d4c416 100644 (file)
@@ -1,3 +1,8 @@
+2004-08-27  Bud Davis  <bdavis9659@comcast.net>
+
+       PR fortran/16597
+       * gfortran.dg/pr16597.f90: New test.
+
 2004-08-26  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        PR c/13801
diff --git a/gcc/testsuite/gfortran.dg/pr16597.f90 b/gcc/testsuite/gfortran.dg/pr16597.f90
new file mode 100644 (file)
index 0000000..ff1dcb8
--- /dev/null
@@ -0,0 +1,27 @@
+! pr 16597
+! libgfortran
+! reading a direct access record after it was written did
+! not always return the correct data.
+
+      program gfbug4
+      implicit none
+
+      integer      strlen
+      parameter    (strlen = 4)
+
+      integer      iunit 
+      character    string *4
+
+      iunit = 99
+      open (UNIT=iunit,FORM='unformatted',ACCESS='direct',RECL=strlen)
+      write (iunit, rec=1) 'ABCD'
+      read (iunit, rec=1) string
+      close (iunit)
+      if (string.ne.'ABCD') call abort
+
+      open (UNIT=iunit,FORM='unformatted',ACCESS='direct',STATUS='scratch',RECL=strlen)
+      write (iunit, rec=1) 'ABCD'
+      read (iunit, rec=1) string
+      close (iunit)
+      if (string.ne.'ABCD') call abort
+      end
index 33e16c9dd31e0096f9a69a294c109b3ef4d8f282..e0039ec0ac98f4b17574cb0ee4511115b8ef7f9b 100644 (file)
@@ -1,3 +1,12 @@
+2004-08-27  Bud Davis  <bdavis9659@comcast.net>
+
+       PR fortran/16597
+       * io/io.h: created typedef for unit_mode.
+       * io/io.h (gfc_unit): added mode to unit structure.
+       * io/transfer.c (data_transfer_init): flush if a write then
+       read is done on a unit (direct access files).
+       * io/rewind.c (st_rewind): Used unit mode instead of global.
+
 2004-08-24  Bud Davis  <bdavis9659@comcast.net>
 
        PR fortran/17143        
index 796a6247f21e26d728e68b1fb54ea95e536a4fc4..d2c15af7ec76621e11e0c8ac8b8dd9a85c659e05 100644 (file)
@@ -144,7 +144,9 @@ typedef enum
 { ADVANCE_YES, ADVANCE_NO, ADVANCE_UNSPECIFIED }
 unit_advance;
 
-
+typedef enum
+{READING, WRITING}
+unit_mode;
 
 /* Statement parameters.  These are all the things that can appear in
    an I/O statement.  Some are inputs and some are outputs, but none
@@ -271,6 +273,7 @@ typedef struct gfc_unit
   { NO_ENDFILE, AT_ENDFILE, AFTER_ENDFILE }
   endfile;
 
+  unit_mode  mode;
   unit_flags flags;
   gfc_offset recl, last_record, maxrec, bytes_left;
 
@@ -299,7 +302,7 @@ typedef struct
   gfc_unit *unit_root;
   int seen_dollar;
 
-  enum {READING, WRITING} mode;
+  unit_mode  mode;
 
   unit_blank blank_status;
   enum {SIGN_S, SIGN_SS, SIGN_SP} sign_status;
index 76fd1948e050710713af7837f3748595fe783595..d9758a6d5ec8c6b4921ee0b77c0c3d3ab646d215 100644 (file)
@@ -40,7 +40,7 @@ st_rewind (void)
                        "Cannot REWIND a file opened for DIRECT access");
       else
        {
-          if (g.mode==WRITING)
+          if (u->mode==WRITING)
             struncate(u->s);
          u->last_record = 0;
          if (sseek (u->s, 0) == FAILURE)
index b6f7c0e0129503dee5d56d4a9d7b23f0749d209f..3800d0b90cb750bd9ce915c93614d65c39614482 100644 (file)
@@ -1044,13 +1044,19 @@ data_transfer_init (int read_flag)
          return;
        }
 
-      /* Position the file.  */
+      /* Check to see if we might be reading what we wrote before  */
+
+      if (g.mode == READING && current_unit->mode  == WRITING)
+         flush(current_unit->s);
 
+      /* Position the file.  */
       if (sseek (current_unit->s,
                (ioparm.rec - 1) * current_unit->recl) == FAILURE)
        generate_error (ERROR_OS, NULL);
     }
 
+  current_unit->mode = g.mode;
+
   /* Set the initial value of flags.  */
 
   g.blank_status = current_unit->flags.blank;