From: Jerry DeLisle Date: Sat, 5 Mar 2011 00:05:34 +0000 (+0000) Subject: backport: [multiple changes] X-Git-Tag: releases/gcc-4.5.3~180 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=761161080a778cb0800cdf0c2bd111ac9ecc64b0;p=thirdparty%2Fgcc.git backport: [multiple changes] 2011-03-04 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-04 Janne Blomqvist Jerry DeLisle 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 Backport from mainline PR libgfortran/47878 * gfortran.dg/pr47878.f90: New test. From-SVN: r170692 --- diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 421912e1386e..818b7622a489 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-03-04 Jerry DeLisle + + Backport from mainline + PR libgfortran/47878 + * gfortran.dg/pr47878.f90: New test. + 2011-03-01 Jason Merrill * 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 index 000000000000..9cc4a0860319 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr47878.f90 @@ -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 diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index ae5b6f7024d9..4b2629b43039 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,19 @@ +2011-03-04 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-04 Janne Blomqvist + Jerry DeLisle + + 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 Kai-Uwe Eckhardt diff --git a/libgfortran/io/fbuf.h b/libgfortran/io/fbuf.h index c82d01b2b988..3a2883bc59a7 100644 --- a/libgfortran/io/fbuf.h +++ b/libgfortran/io/fbuf.h @@ -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 diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 0f3efcca4548..5787f72d46a8 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -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; }