From: Jerry DeLisle Date: Mon, 7 Mar 2011 03:08:08 +0000 (+0000) Subject: backport: re PR fortran/47878 (187.facerec miscompares) X-Git-Tag: releases/gcc-4.4.6~94 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=797401851e2b4b89e6c03d5c00754abbd34bc717;p=thirdparty%2Fgcc.git backport: re PR fortran/47878 (187.facerec miscompares) 2011-03-06 Jakub Jelinek 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 Jerry DeLisle 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 --- diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 31423f4a1591..9d9d5eea0af7 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,19 @@ +2011-03-06 Jakub Jelinek + + 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 + Jerry DeLisle + + 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 Kai-Uwe Eckhardt diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 25b2d5ced0bd..4562873a1762 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -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); diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 96a44f524e34..0b8793b3831c 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -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; }