This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran 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]

[patch, libfortran] PR43298 Fortran library does not read in NaN -Inf or Inf


This attached patch adds code to read these special cases. The code is self explanatory. This added feature is for formatted READ.

As a follow-up patch we can consider the contents of the parenthesis with NAN() and explicitly set the result. I will also be looking at how to handle signs.

Regression tested on x86-64. testing on other platforms would be appreciated.

OK for trunk?

Regards,

Jerry

2010-06-27 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR libfortran/43298
	* io/read.c: Add code to parse and read Inf, Infinity, NaN, and Nan with
	optional parenthesis.
Index: read.c
===================================================================
--- read.c	(revision 161472)
+++ read.c	(working copy)
@@ -810,6 +810,60 @@ read_f (st_parameter_dt *dtp, const fnode *f, char
   if (w == 0)
     goto zero;
 
+
+  /* Check for Infinity or NaN.  */    
+  if (unlikely ((w >= 3 && (*p == 'i' || *p == 'I' || *p == 'n' || *p == 'N'))))
+    {
+      int i;
+      int seen_space = 0;
+      int seen_paren = 0;
+
+      /* Scan through the buffer keeping track of spaces and parenthesis. We
+	 null terminate the string as soon as we see a left paren or if we are
+	 BLANK_NULL mode.  Leading spaces have already been skipped above,
+	 trailing spaces spaces are ignored by converrting to '\0'. A space
+	 between "NaN" and the optional perenthesis is not permitted.  */
+      for (i = 0; i < w; i++)
+	{
+	  buffer[i] = tolower (p[i]);
+	  if (!seen_paren && seen_space && buffer[i] != ' ')
+	    goto bad_float;
+	  if (buffer[i] == '(')
+	    {
+	      seen_paren = 1;
+	      buffer[i] = '\0';
+	    }
+	  if (buffer[i] == ')')
+	    {
+	      if (!seen_paren)
+	        goto bad_float;
+	      else
+	        seen_paren = 0;
+	    }
+	  if (buffer[i] == ' ' && !seen_paren)
+	    {
+	      seen_space = 1;
+	      if (dtp->u.p.blank_status == BLANK_ZERO)
+		buffer[i] = '0';
+	      else /* Ignore leading and trailing blanks.  */
+	      	buffer[i] = '\0';
+	    }
+	}
+	 
+      buffer[w] = '\0';
+
+      /* If we did not see a closing parenthesis, we have a bad float.  */
+      if (seen_paren)
+        goto bad_float;
+      if (strcmp (buffer, "inf") != 0
+	  && strcmp (buffer, "nan") != 0
+	  && strcmp (buffer, "infinity") != 0)
+	goto bad_float;
+
+      convert_real (dtp, dest, buffer, length);
+      return;
+    }
+
   /* Process the mantissa string.  */
   while (w > 0)
     {
! { dg-do run }
! PR43298  Fortran library does not read in NaN -Inf or Inf
! Test case prepared by Jerry DeLisle  <jvdelisle@gcc.gnu.org>
program pr43298
  real(4) :: x4(7)
  real(8) :: x8(7)
  character(80) :: output

open(10, status='scratch')
!                0123456789012345678901234567890123456789012345678901234567890123456789
write(10,'(a)') "inf           nan   infinity  -NaN(dxyz)   -INf    NAN       InFiNiTy"
rewind(10)
read(10,'(7f10.3)') x4
rewind(10)
read(10,'(7f10.3)') x8
write (output, '("x4 =",7G6.0)') x4
if (output.ne."x4 =  +Inf   NaN  +Inf   NaN  +Inf   NaN  +Inf") call abort
write (output, '("x8 =",7G6.0)') x8
if (output.ne."x8 =  +Inf   NaN  +Inf   NaN  +Inf   NaN  +Inf") call abort
!print '("x4 =",7G6.0)', x4
!print '("x8 =",7G6.0)', x8

end program pr43298


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