This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[patch, libfortran] PR43298 Fortran library does not read in NaN -Inf or Inf
- From: Jerry DeLisle <jvdelisle at verizon dot net>
- To: gfortran <fortran at gcc dot gnu dot org>
- Cc: gcc patches <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 27 Jun 2010 12:40:25 -0700
- Subject: [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