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]

Re: [patch, libgfortran] PR29563 Internal read loses data FIX


Steve Kargl wrote:
On Wed, Oct 25, 2006 at 09:06:17PM -0700, Jerry DeLisle wrote:
2006-10-25 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR libgfortran/29563
	* io/io.h (st_parameter_dt): Add new flag at_eof.
	* io/list_read.c (next_char): Set flag when EOF and return '\n' to
	signal EOR.  Check flag on next call and jump out.
	* io/unit.c (get_internal_unit): Initialize new flag.


OK for 4.3. Tentative OK for 4.2 (ask markm).



After committing this to 4.3 branch I discovered a glitch. I was just staring at it and thinking and another test case popped into my mind. The attached patch fixes it. I was failing to return a '\n' at the end of each record so if the character array unit is completely full, with no separators, we would get an error. The attached patch and additional test case illustrates this.


Regression tested OK.

I will commit the fix to 4.3 shortly.

Please accept my apologies.

Jerry
Index: io/list_read.c
===================================================================
*** io/list_read.c	(revision 118059)
--- io/list_read.c	(working copy)
*************** next_char (st_parameter_dt *dtp)
*** 173,185 ****
        /* Check for "end-of-record" condition.  */
        if (dtp->u.p.current_unit->bytes_left == 0)
  	{
  	  record = next_array_record (dtp, dtp->u.p.current_unit->ls);
  
  	  /* Check for "end-of-file" condition.  */      
  	  if (record == 0)
  	    {
  	      dtp->u.p.at_eof = 1;
- 	      c = '\n';
  	      goto done;
  	    }
  
--- 173,185 ----
        /* Check for "end-of-record" condition.  */
        if (dtp->u.p.current_unit->bytes_left == 0)
  	{
+ 	  c = '\n';
  	  record = next_array_record (dtp, dtp->u.p.current_unit->ls);
  
  	  /* Check for "end-of-file" condition.  */      
  	  if (record == 0)
  	    {
  	      dtp->u.p.at_eof = 1;
  	      goto done;
  	    }
  
*************** next_char (st_parameter_dt *dtp)
*** 188,193 ****
--- 188,194 ----
  	    longjmp (*dtp->u.p.eof_jump, 1);
  
  	  dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
+ 	  goto done;
  	}
      }
  
! { dg-do run }
! PR29563 Internal read loses data.
! Test from test case. Submitted by Jerry DeLisle  <jvdelisle@gcc.gnu.org>
! Without patch, last value in array was being skipped in the read.
program pr29563
  character(len=10), dimension(3)::arraydata = (/' 1 2 3',' 4 5 6',' 7 8 9'/)
  real(kind=8), dimension(3,3) :: tmp
  tmp = 0.0
  read(arraydata,*,iostat=iostat)((tmp(i,j),j=1,3),i=1,3)
  if (tmp(3,3)-9.0.gt.0.0000001) call abort()
end program pr29563
! { dg-do run }
! PR29563 Internal read loses data.
! Test case submitted by Jerry DeLisle  <jvdelisle@gcc.gnu.org>
! Without patch, values get muddled.
program pr29563
  character(len=4), dimension(3)::arraydata = (/'1123',' 456','789 '/)
  real(kind=8), dimension(3) :: tmp
  read(arraydata,*,iostat=iostat)tmp
  if (tmp(1).ne.1123.0) call abort()
  if (tmp(2).ne.456.0) call abort()
  if (tmp(3).ne.789.0) call abort()
end program pr29563

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