]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: [multiple changes]
authorJerry DeLisle <jvdelisle@gcc.gnu.org>
Sat, 5 Mar 2011 00:05:34 +0000 (00:05 +0000)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Sat, 5 Mar 2011 00:05:34 +0000 (00:05 +0000)
2011-03-04  Jakub Jelinek  <jakub@redhat.com>

Backport from mainline
PR fortran/47878
* io/transfer.c (read_sf): Call fbuf_getptr only at the end,
and subtract n, dtp->u.p.sf_seen_eor and seen_comma from it.

2011-03-04  Janne Blomqvist  <jb@gcc.gnu.org>
    Jerry DeLisle    <jvdelisle@gcc.gnu.org>

Backport from mainline
PR libfortran/47694
* io/fbuf.h (fbuf_getptr): New inline function.
* io/transfer.c (read_sf): Use fbuf_getptr and fbuf_getc to scan
through the string instead of fbuf_read.

2011-03-04  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

Backport from mainline
PR libgfortran/47878
* gfortran.dg/pr47878.f90: New test.

From-SVN: r170692

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

index 421912e1386e1868d985fb1c37f5dc45229c6b0d..818b7622a48975faf173ee83e7d3dd7198879be4 100644 (file)
@@ -1,3 +1,9 @@
+2011-03-04  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
+
+       Backport from mainline
+       PR libgfortran/47878
+       * gfortran.dg/pr47878.f90: New test.
+
 2011-03-01  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/cpp0x/lambda/lambda-98.C: New.
diff --git a/gcc/testsuite/gfortran.dg/pr47878.f90 b/gcc/testsuite/gfortran.dg/pr47878.f90
new file mode 100644 (file)
index 0000000..9cc4a08
--- /dev/null
@@ -0,0 +1,10 @@
+! PR fortran/47878
+! { dg-do run }
+  integer :: a(5)
+  open (99, recl = 40)
+  write (99, '(5i3)') 1, 2, 3
+  rewind (99)
+  read (99, '(5i3)') a
+  if (any (a.ne.(/1, 2, 3, 0, 0/))) call abort 
+  close (99, status = 'delete')
+end
index ae5b6f7024d99aaaffd96336dd61cdab7503e822..4b2629b430397fef44188d8c9a8ac3a342fca8df 100644 (file)
@@ -1,3 +1,19 @@
+2011-03-04  Jakub Jelinek  <jakub@redhat.com>
+
+       Backport from mainline
+       PR fortran/47878
+       * io/transfer.c (read_sf): Call fbuf_getptr only at the end,
+       and subtract n, dtp->u.p.sf_seen_eor and seen_comma from it.
+
+2011-03-04  Janne Blomqvist  <jb@gcc.gnu.org>
+           Jerry DeLisle    <jvdelisle@gcc.gnu.org>
+
+       Backport from mainline
+       PR libfortran/47694
+       * io/fbuf.h (fbuf_getptr): New inline function.
+       * io/transfer.c (read_sf): Use fbuf_getptr and fbuf_getc to scan
+       through the string instead of fbuf_read.
+
 2011-02-22  Tobias Burnus  <burnus@net-b.de>
            Kai-Uwe Eckhardt  <kuehro@gmx.de>
 
index c82d01b2b988b8e568e284ee70c1c0899300670a..3a2883bc59a7f29adf252a7ecba066db70429f10 100644 (file)
@@ -78,4 +78,10 @@ fbuf_getc (gfc_unit * u)
   return fbuf_getc_refill (u);
 }
 
+static inline char *
+fbuf_getptr (gfc_unit * u)
+{
+  return (char*) (u->fbuf->buf + u->fbuf->pos);
+}
+
 #endif
index 0f3efcca45487d373624297088612638e6325223..5787f72d46a835acd757da02a3474ef52e5fa58c 100644 (file)
@@ -236,16 +236,16 @@ static char *
 read_sf (st_parameter_dt *dtp, int * length)
 {
   static char *empty_string[0];
-  char *base, *p, q;
+  int q, q2;
   int n, lorig, seen_comma;
 
   /* If we have seen an eor previously, return a length of 0.  The
-     caller is responsible for correctly padding the input field.  */
*      caller is responsible for correctly padding the input field.  */
   if (dtp->u.p.sf_seen_eor)
     {
       *length = 0;
       /* Just return something that isn't a NULL pointer, otherwise the
-         caller thinks an error occured.  */
*          caller thinks an error occured.  */
       return (char*) empty_string;
     }
 
@@ -253,42 +253,36 @@ read_sf (st_parameter_dt *dtp, int * length)
 
   /* Read data into format buffer and scan through it.  */
   lorig = *length;
-  base = p = fbuf_read (dtp->u.p.current_unit, length);
-  if (base == NULL)
-    return NULL;
 
   while (n < *length)
     {
-      q = *p;
-
-      if (q == '\n' || q == '\r')
+      q = fbuf_getc (dtp->u.p.current_unit);
+      if (q == EOF)
+       break;
+      else if (q == '\n' || q == '\r')
        {
          /* Unexpected end of line. Set the position.  */
-         fbuf_seek (dtp->u.p.current_unit, n + 1 ,SEEK_CUR);
          dtp->u.p.sf_seen_eor = 1;
 
          /* If we see an EOR during non-advancing I/O, we need to skip
           the rest of the I/O statement.  Set the corresponding flag.  */
*          the rest of the I/O statement.  Set the corresponding flag.  */
          if (dtp->u.p.advance_status == ADVANCE_NO || dtp->u.p.seen_dollar)
            dtp->u.p.eor_condition = 1;
            
          /* If we encounter a CR, it might be a CRLF.  */
          if (q == '\r') /* Probably a CRLF */
            {
-             /* See if there is an LF. Use fbuf_read rather then fbuf_getc so
-                the position is not advanced unless it really is an LF.  */
-             int readlen = 1;
-             p = fbuf_read (dtp->u.p.current_unit, &readlen);
-             if (*p == '\n' && readlen == 1)
-               {
-                 dtp->u.p.sf_seen_eor = 2;
-                 fbuf_seek (dtp->u.p.current_unit, 1 ,SEEK_CUR);
-               }
+             /* See if there is an LF.  */
+             q2 = fbuf_getc (dtp->u.p.current_unit);
+             if (q2 == '\n')
+               dtp->u.p.sf_seen_eor = 2;
+             else if (q2 != EOF) /* Oops, seek back.  */
+               fbuf_seek (dtp->u.p.current_unit, -1, SEEK_CUR);
            }
 
          /* Without padding, terminate the I/O statement without assigning
           the value.  With padding, the value still needs to be assigned,
-            so we can just continue with a short read.  */
*          the value.  With padding, the value still needs to be assigned,
*                  so we can just continue with a short read.  */
          if (dtp->u.p.current_unit->pad_status == PAD_NO)
            {
              generate_error (&dtp->common, LIBERROR_EOR, NULL);
@@ -299,25 +293,23 @@ read_sf (st_parameter_dt *dtp, int * length)
          goto done;
        }
       /*  Short circuit the read if a comma is found during numeric input.
        The flag is set to zero during character reads so that commas in
-         strings are not ignored  */
-      if (q == ',')
*       The flag is set to zero during character reads so that commas in
*               strings are not ignored  */
+      else if (q == ',')
        if (dtp->u.p.sf_read_comma == 1)
          {
             seen_comma = 1;
            notify_std (&dtp->common, GFC_STD_GNU,
                        "Comma in formatted numeric read.");
-           *length = n;
            break;
          }
       n++;
-      p++;
-    } 
+    }
 
-  fbuf_seek (dtp->u.p.current_unit, n + seen_comma, SEEK_CUR);
+  *length = n;
 
   /* A short read implies we hit EOF, unless we hit EOR, a comma, or
-     some other stuff. Set the relevant flags.  */
*      some other stuff. Set the relevant flags.  */
   if (lorig > *length && !dtp->u.p.sf_seen_eor && !seen_comma)
     {
       if (n > 0)
@@ -352,7 +344,12 @@ read_sf (st_parameter_dt *dtp, int * length)
   if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
     dtp->u.p.size_used += (GFC_IO_INT) n;
 
-  return base;
+  /* We can't call fbuf_getptr before the loop doing fbuf_getc, because
+ *      fbuf_getc might reallocate the buffer.  So return current pointer
+ *           minus all the advances, which is n plus up to two characters
+ *                of newline or comma.  */
+  return fbuf_getptr (dtp->u.p.current_unit)
+        - n - dtp->u.p.sf_seen_eor - seen_comma;
 }