From bd72d66cb5f8450f631da7149bf066f865d56338 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Tue, 31 Aug 2004 15:53:31 +0000 Subject: [PATCH] transfer.c (read_sf): Rename uinty to readlen. * io/transfer.c (read_sf): Rename uinty to readlen. Detect EOF. (finalize_transfer): Move setjmp after namlist IO. * io/unix.c (mem_alloc_r_at): Calculate remaining length correctly. testsuite/ * gfortran.dg/eof_1.f90: New test. From-SVN: r86831 --- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gfortran.dg/eof_1.f90 | 18 ++++++++++++++++ libgfortran/ChangeLog | 6 ++++++ libgfortran/io/transfer.c | 33 ++++++++++++++++++----------- libgfortran/io/unix.c | 2 +- 5 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/eof_1.f90 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0bca0f17229..df86733ee71 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-08-31 Paul Brook + + * gfortran.dg/eof_1.f90: New test. + 2004-08-31 Paul Brook * gfortran.dg/list_read_1.f90: New file. diff --git a/gcc/testsuite/gfortran.dg/eof_1.f90 b/gcc/testsuite/gfortran.dg/eof_1.f90 new file mode 100644 index 00000000000..05726bd1413 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/eof_1.f90 @@ -0,0 +1,18 @@ +! { dg-do run } +! Program to test for proper EOF errors when reading past the end of a file. +! We used to get this wrong when a formatted read followed a list formatted +! read. +program eof_1 + character(len=5) :: s + + open (unit=11, status="SCRATCH") + write (11, '(a)') "Hello" + rewind(11) + read(11, *) s + if (s .ne. "Hello") call abort + read(11, '(a5)', end=10) s + call abort +10 continue + close (11) +end + diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 28329d2608c..1c76245bb39 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,9 @@ +2004-08-31 Paul Brook + + * io/transfer.c (read_sf): Rename uinty to readlen. Detect EOF. + (finalize_transfer): Move setjmp after namlist IO. + * io/unix.c (mem_alloc_r_at): Calculate remaining length correctly. + 2004-08-31 Paul Brook * list_read.c (eat_separator): Set at_eo when a '/' is seen. diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 5d4dcd592a0..ca920724b0d 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -119,7 +119,7 @@ read_sf (int *length) { static char data[SCRATCH_SIZE]; char *base, *p, *q; - int n, unity; + int n, readlen; if (*length > SCRATCH_SIZE) p = base = line_buffer = get_mem (*length); @@ -129,24 +129,33 @@ read_sf (int *length) memset(base,'\0',*length); current_unit->bytes_left = options.default_recl; - unity = 1; + readlen = 1; n = 0; do { if (is_internal_unit()) { - /* unity may be modified inside salloc_r if + /* readlen may be modified inside salloc_r if is_internal_unit() is true. */ - unity = 1; + readlen = 1; } - q = salloc_r (current_unit->s, &unity); + q = salloc_r (current_unit->s, &readlen); if (q == NULL) break; - if (*q == '\n') + /* If we have a line without a terminating \n, drop through to + EOR below. */ + if (readlen < 1 & n == 0) { + generate_error (ERROR_END, NULL); + return NULL; + } + + if (readlen < 1 || *q == '\n') + { + /* ??? What is this for? */ if (current_unit->unit_number == options.stdin_unit) { if (n <= 0) @@ -1345,12 +1354,6 @@ static void finalize_transfer (void) { - if (setjmp (g.eof_jump)) - { - generate_error (ERROR_END, NULL); - return; - } - if ((ionml != NULL) && (ioparm.namelist_name != NULL)) { if (ioparm.namelist_read_mode) @@ -1363,6 +1366,12 @@ finalize_transfer (void) if (current_unit == NULL) return; + if (setjmp (g.eof_jump)) + { + generate_error (ERROR_END, NULL); + return; + } + if (ioparm.list_format && g.mode == READING) finish_list_read (); else diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 0c652581c04..33d7fda4514 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -751,7 +751,7 @@ mem_alloc_r_at (unix_stream * s, int *len, gfc_offset where) s->logical_offset = where + *len; - n = (where - s->buffer_offset) - s->active; + n = s->buffer_offset + s->active - where; if (*len > n) *len = n; -- 2.30.2