This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gfortran] EOF in formatted read


The following patch makes some tweaks to End-of-File handling for formatted 
reads.
The main bit is checking for a zero-length read (ie. EOF) in read_sf.
It also fixes latent bug in mem_alloc_r_at where the remaining length was 
calculated incorrectly..
The finalize_transfer changes is because namelist_read defines its own EOF 
handler.

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.
testsuite/
 * gfortran.dg/eof_1.f90: New test.

Index: io/transfer.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libgfortran/io/transfer.c,v
retrieving revision 1.14
diff -u -p -r1.14 transfer.c
--- io/transfer.c 31 Aug 2004 14:06:48 -0000 1.14
+++ io/transfer.c 31 Aug 2004 15:33:37 -0000
@@ -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
Index: io/unix.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libgfortran/io/unix.c,v
retrieving revision 1.7
diff -u -p -r1.7 unix.c
--- io/unix.c 5 Jul 2004 01:19:08 -0000 1.7
+++ io/unix.c 31 Aug 2004 14:45:15 -0000
@@ -751,7 +751,7 @@ mem_alloc_r_at (unix_stream * s, int *le
 
   s->logical_offset = where + *len;
 
-  n = (where - s->buffer_offset) - s->active;
+  n = s->buffer_offset + s->active - where;
   if (*len > n)
     *len = n;
 

Attachment: eof_1.f90
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]