]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR fortran/47878 (187.facerec miscompares)
authorJerry DeLisle <jvdelisle@gcc.gnu.org>
Mon, 7 Mar 2011 03:08:08 +0000 (03:08 +0000)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Mon, 7 Mar 2011 03:08:08 +0000 (03:08 +0000)
2011-03-06  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-06  Janne Blomqvist  <jb@gcc.gnu.org>
    Jerry DeLisle    <jvdelisle@gcc.gnu.org>

Backport from mainline
PR libfortran/47694
* io/io.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.

From-SVN: r170732

libgfortran/ChangeLog
libgfortran/io/io.h
libgfortran/io/transfer.c

index 31423f4a1591ef5b99eb4e827fc6fa5c2dab6489..9d9d5eea0af7c668afa7b4fedcd57aabf0205eeb 100644 (file)
@@ -1,3 +1,19 @@
+2011-03-06  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-06  Janne Blomqvist  <jb@gcc.gnu.org>
+           Jerry DeLisle    <jvdelisle@gcc.gnu.org>
+
+       Backport from mainline
+       PR libfortran/47694
+       * io/io.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 25b2d5ced0bd9d4813e94830cac02b4ad53933a4..4562873a176201e86699341cccc3f9400929a6cf 100644 (file)
@@ -1013,6 +1013,12 @@ 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);
+}
+
 /* lock.c */
 extern void free_ionml (st_parameter_dt *);
 internal_proto(free_ionml);
index 96a44f524e34a908de75fb9e77ca2eb3fe9d3d60..0b8793b3831c06158280bb1e7650b3124f324683 100644 (file)
@@ -222,7 +222,7 @@ 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
@@ -239,18 +239,15 @@ 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
@@ -261,15 +258,12 @@ read_sf (st_parameter_dt *dtp, int * length)
          /* 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
@@ -287,20 +281,18 @@ read_sf (st_parameter_dt *dtp, int * length)
       /*  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 == ',')
+      else if (q == ',')
        if (dtp->u.p.sf_read_comma == 1)
          {
-            seen_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.  */
@@ -338,7 +330,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;
 }