aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gfortran.dg/eof_1.f9018
-rw-r--r--libgfortran/ChangeLog6
-rw-r--r--libgfortran/io/transfer.c33
-rw-r--r--libgfortran/io/unix.c2
5 files changed, 50 insertions, 13 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0bca0f1..df86733 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2004-08-31 Paul Brook <paul@codesourcery.com>
+ * gfortran.dg/eof_1.f90: New test.
+
+2004-08-31 Paul Brook <paul@codesourcery.com>
+
* gfortran.dg/list_read_1.f90: New file.
2004-08-30 Mark Mitchell <mark@codesourcery.com>
diff --git a/gcc/testsuite/gfortran.dg/eof_1.f90 b/gcc/testsuite/gfortran.dg/eof_1.f90
new file mode 100644
index 0000000..05726bd
--- /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 28329d2..1c76245 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,5 +1,11 @@
2004-08-31 Paul Brook <paul@codesourcery.com>
+ * 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 <paul@codesourcery.com>
+
* list_read.c (eat_separator): Set at_eo when a '/' is seen.
2004-08-31 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 5d4dcd5..ca92072 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 0c65258..33d7fda 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;