public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch, libfortran] PR34427 namelist input of inf-nan
@ 2007-12-16  3:32 Jerry DeLisle
  2007-12-16  3:33 ` Jerry DeLisle
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Jerry DeLisle @ 2007-12-16  3:32 UTC (permalink / raw)
  To: Fortran List; +Cc: gcc-patches, H. J. Lu

[-- Attachment #1: Type: text/plain, Size: 2066 bytes --]

Hi folks,   HJL will you please test this patch on SPEC?

This patch is a follow-up patch to Tobias patch for this PR.

This patch addresses a failure we got when no delimiter other than a line end 
was given between a value and a subsequent object name.

This was caused by reading the line end '\n' and saving it as part of the object 
name string.  I check for this in get_name and don't do that. (A latent bug sort of)

To handle multiple intervening lines and spaces, I added code to eat all the 
preceding line ends and spaces before checking for an "=" when trying to see if 
we are reading a value "Infinity" or an object name "Infinity".  With this patch 
we can have practically unlimited spaces and line ends since we just skip them.

Note: F95 Standard 10.9: "The end of a record has the same effect as a blank 
character, unless it is within a character constant."

We don't need to count the characters in the object name because as soon as we 
have a non separator after "infinity" we unwind. The get_name code will then 
takeover.  Likewise when looking for the "=", since we know we already have a 
separator at that point if the next character is "=" it must be an object name 
or a misplaced "=".

(side note: This is a quite different situation from read_logical where any 
value starting with a 't' or 'f' is interpreted as .true. or .false. value 
unless it is an object name.  The only way to know in that case is to read up to 
64 characters in the name and not hit a '='.)

I revised namelist_42.f90 and added namelist_43.f90 to illustrate some of the 
issues.  I have not gone through some of the other data type reads to see what 
happens for them in the intervening spaces and lines situations.  I will do that 
later.

Regression tested on x86-64.

OK for trunk?

Jerry

2007-12-15  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR fortran/34427
	* io/list_read.c (read_real): Handle intervening line ends and spaces.
	(get_name): Don't push separators to saved_string.
	(eat_separator): If in namelist mode eat spaces and line ends as well.

[-- Attachment #2: namelist_42.f90 --]
[-- Type: text/x-fortran, Size: 823 bytes --]

! { dg-do run }
! { dg-options "-mieee" { target sh*-*-* } }
!
! PR fortran/34427
!
! Check that namelists and the real values Inf, NaN, Infinity
! properly coexist.
!
 PROGRAM TEST
  IMPLICIT NONE
  real , DIMENSION(11) ::foo 
  integer :: infinity
  NAMELIST /nl/ foo
  NAMELIST /nl/ infinity
  foo = -1.0
  infinity = -1

  open (10, status="scratch")
! Works:
  write (10,*) " &nl foo = 5, 5, 5, nan, infinity, infinity "
  write (10,*)
  write (10,*) "      = 1, /"
! Does not work
  !write (10,*) " &nl foo = 5, 5, 5, nan, infinity, infinity"
  !write (10,*) "      = 1, /"
  rewind (10)
  READ (10, NML = nl)
  CLOSE (10)

  if(infinity /= 1) call abort()
  if(any(foo(1:3) /= [5.0, 5.0, 5.0]) .or. .not.isnan(foo(4)) &
     .or. foo(5) <= huge(foo) .or. any(foo(6:11) /= -1.0)) &
    call abort()
 END PROGRAM TEST

[-- Attachment #3: namelist_43.f90 --]
[-- Type: text/x-fortran, Size: 1062 bytes --]

! { dg-do run }
! { dg-options "-mieee" { target sh*-*-* } }
!
! PR fortran/34427
!
! Check that namelists and the real values Inf, NaN, Infinity
! properly coexist with interceding line ends and spaces.
!
PROGRAM TEST
  IMPLICIT NONE
  real , DIMENSION(10) ::foo 
  integer :: infinity
  integer :: numb
  NAMELIST /nl/ foo
  NAMELIST /nl/ infinity
  foo = -1.0
  infinity = -1

  open (10, status="scratch")

  write (10,'(a)') " &nl foo(1:6) = 5, 5, 5, nan, infinity"
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)') "infinity"
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)') "         "
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)')
  write (10,'(a)') "=1/"
  rewind (10)
  READ (10, NML = nl)
  CLOSE (10)
  if(infinity /= 1) call abort
  if(any(foo(1:3) /= [5.0, 5.0, 5.0]) .or. .not.isnan(foo(4)) &
     .or. (foo(5) <= huge(foo)) .or. any(foo(6:10) /= -1.0)) &
    call abort
END PROGRAM TEST

[-- Attachment #4: pr34427-2.diff --]
[-- Type: text/x-patch, Size: 1407 bytes --]

Index: list_read.c
===================================================================
--- list_read.c	(revision 130941)
+++ list_read.c	(working copy)
@@ -316,6 +316,13 @@ eat_separator (st_parameter_dt *dtp)
 
     case '\n':
       dtp->u.p.at_eol = 1;
+      if (dtp->u.p.namelist_mode)
+	{
+	  do
+	    c = next_char (dtp);
+	  while (c == '\n' || c == '\r' || c == ' ');
+	  unget_char (dtp, c);
+	}
       break;
 
     case '!':
@@ -1578,20 +1585,22 @@ read_real (st_parameter_dt *dtp, int len
       l_push_char (dtp, c);
     }
 
-  if (!is_separator (c) || c == '=')
+  if (!is_separator (c))
     goto unwind;
 
-  if (dtp->u.p.namelist_mode && c != ',' && c != '/')
-    for (i = 0; i < 63; i++)
-    { 
-      eat_spaces (dtp);
-      c = next_char (dtp);
-      l_push_char (dtp, c);
-      if (c == '=')
-	goto unwind;
+  if (dtp->u.p.namelist_mode)
+    {	
+      if (c == ' ' || c =='\n' || c == '\r')
+	{
+	  do
+	    c = next_char (dtp);
+	  while (c == ' ' || c =='\n' || c == '\r');
 
-      if (c == ',' || c == '/' || !is_separator(c))
-	break;
+	  l_push_char (dtp, c);
+
+	  if (c == '=')
+	    goto unwind;
+	}
     }
 
   if (is_inf)
@@ -2594,7 +2603,8 @@ get_name:
 
   do
     {
-      push_char (dtp, tolower(c));
+      if (!is_separator (c))
+	push_char (dtp, tolower(c));
       c = next_char (dtp);
     } while (!( c=='=' || c==' ' || c=='\t' || c =='(' || c =='%' ));
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch, libfortran] PR34427 namelist input of inf-nan
  2007-12-16  3:32 [patch, libfortran] PR34427 namelist input of inf-nan Jerry DeLisle
@ 2007-12-16  3:33 ` Jerry DeLisle
  2007-12-16  6:48 ` H.J. Lu
  2007-12-16 14:32 ` Tobias Burnus
  2 siblings, 0 replies; 5+ messages in thread
From: Jerry DeLisle @ 2007-12-16  3:33 UTC (permalink / raw)
  To: Fortran List; +Cc: gcc-patches, H. J. Lu

[-- Attachment #1: Type: text/plain, Size: 71 bytes --]

Oops, I sent the old namelist_42.f90.  Here is the new version.

Jerry

[-- Attachment #2: namelist_42.f90 --]
[-- Type: text/x-fortran, Size: 1116 bytes --]

! { dg-do run }
! { dg-options "-mieee" { target sh*-*-* } }
!
! PR fortran/34427
!
! Check that namelists and the real values Inf, NaN, Infinity
! properly coexist.
!
 PROGRAM TEST
  IMPLICIT NONE
  real , DIMENSION(11) ::foo 
  integer :: infinity
  NAMELIST /nl/ foo
  NAMELIST /nl/ infinity
  foo = -1.0
  infinity = -1

  open (10, status="scratch")
! Works:
  write (10,*) " &nl foo = 5, 5, 5, nan, infinity, infinity "
  write (10,*)
  write (10,*) "      = 1, /"
  rewind (10)
  READ (10, NML = nl)
  close (10)

  if(infinity /= 1) call abort()
  if(any(foo(1:3) /= [5.0, 5.0, 5.0]) .or. .not.isnan(foo(4)) &
     .or. foo(5) <= huge(foo) .or. any(foo(6:11) /= -1.0)) &
    call abort()
! Works too:
  foo = -1.0
  infinity = -1

  open (10, status="scratch")
  rewind (10)
  write (10,'(a)') "&nl foo = 5, 5, 5, nan, infinity, infinity"
  write (10,'(a)') "=1,/"
  rewind (10)
  READ (10, NML = nl)
  CLOSE (10)

  if(infinity /= 1) call abort()
  if(any(foo(1:3) /= [5.0, 5.0, 5.0]) .or. .not.isnan(foo(4)) &
     .or. foo(5) <= huge(foo) .or. any(foo(6:11) /= -1.0)) &
    call abort()
 END PROGRAM TEST

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch, libfortran] PR34427 namelist input of inf-nan
  2007-12-16  3:32 [patch, libfortran] PR34427 namelist input of inf-nan Jerry DeLisle
  2007-12-16  3:33 ` Jerry DeLisle
@ 2007-12-16  6:48 ` H.J. Lu
  2007-12-16 14:32 ` Tobias Burnus
  2 siblings, 0 replies; 5+ messages in thread
From: H.J. Lu @ 2007-12-16  6:48 UTC (permalink / raw)
  To: Jerry DeLisle; +Cc: Fortran List, gcc-patches

On Sat, Dec 15, 2007 at 07:13:50PM -0800, Jerry DeLisle wrote:
> Hi folks,   HJL will you please test this patch on SPEC?

Please feel free to check it in if there are no regressions in gcc
testsuites. My SPEC testers will pick it up in a few days after it
is checked in. If there is a problem with SPEC, I will let you
know :-(.  Thanks.

>
> This patch is a follow-up patch to Tobias patch for this PR.
>
> This patch addresses a failure we got when no delimiter other than a line 
> end was given between a value and a subsequent object name.
>
> This was caused by reading the line end '\n' and saving it as part of the 
> object name string.  I check for this in get_name and don't do that. (A 
> latent bug sort of)
>

...


H.J.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch, libfortran] PR34427 namelist input of inf-nan
  2007-12-16  3:32 [patch, libfortran] PR34427 namelist input of inf-nan Jerry DeLisle
  2007-12-16  3:33 ` Jerry DeLisle
  2007-12-16  6:48 ` H.J. Lu
@ 2007-12-16 14:32 ` Tobias Burnus
  2007-12-16 15:53   ` Jerry DeLisle
  2 siblings, 1 reply; 5+ messages in thread
From: Tobias Burnus @ 2007-12-16 14:32 UTC (permalink / raw)
  To: Jerry DeLisle; +Cc: Fortran List, gcc-patches, H. J. Lu

Jerry DeLisle wrote:
> 2007-12-15  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
>
>     PR fortran/34427
>     * io/list_read.c (read_real): Handle intervening line ends and
> spaces.
>     (get_name): Don't push separators to saved_string.
>     (eat_separator): If in namelist mode eat spaces and line ends as
> well.
The patch is OK, but I have some comments/questions:

@@ -316,6 +316,13 @@ eat_separator (st_parameter_dt *dtp)
 
     case '\n':
       dtp->u.p.at_eol = 1;
+      if (dtp->u.p.namelist_mode)
+	{
+	  do
+	    c = next_char (dtp);
+	  while (c == '\n' || c == '\r' || c == ' ');
+	  unget_char (dtp, c);
+	}
       break;


I wonder whether one should do something similar for '\r'. If I recall
correctly, the normal line-break character on MacOS was (is?) '\r'
(while Unix has '\n' and Windows "\r\n").


Additionally, I think one can replace:

 exp2:
  if (!isdigit (c))
    {
      if (c == 'i' || c == 'I' || c == 'n' || c == 'N')
        goto inf_nan;
      else
        goto bad;
    }

by

 exp2:
  if (!isdigit (c))
    goto bad;

I changed this in my original Inf/NaN patch to the upper version, but
you correctly remarked that it does not make much sense to have it for
exp2. (But I forgot to change it back when I checked the patch in.) You
can undo my change if you want.

Tobias

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch, libfortran] PR34427 namelist input of inf-nan
  2007-12-16 14:32 ` Tobias Burnus
@ 2007-12-16 15:53   ` Jerry DeLisle
  0 siblings, 0 replies; 5+ messages in thread
From: Jerry DeLisle @ 2007-12-16 15:53 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: Fortran List, gcc-patches

Tobias Burnus wrote:
> Jerry DeLisle wrote:
>> 2007-12-15  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
>>
>>     PR fortran/34427
>>     * io/list_read.c (read_real): Handle intervening line ends and
>> spaces.
>>     (get_name): Don't push separators to saved_string.
>>     (eat_separator): If in namelist mode eat spaces and line ends as
>> well.
> The patch is OK, but I have some comments/questions:
> 
> @@ -316,6 +316,13 @@ eat_separator (st_parameter_dt *dtp)
>  
>      case '\n':
>        dtp->u.p.at_eol = 1;
> +      if (dtp->u.p.namelist_mode)
> +	{
> +	  do
> +	    c = next_char (dtp);
> +	  while (c == '\n' || c == '\r' || c == ' ');
> +	  unget_char (dtp, c);
> +	}
>        break;
> 
> 
> I wonder whether one should do something similar for '\r'. If I recall
> correctly, the normal line-break character on MacOS was (is?) '\r'
> (while Unix has '\n' and Windows "\r\n").

According to Wikipedia, the '\r' is used in MacOS up to version 9.  So we better 
accommodate it just in case.

> 
> 
> Additionally, I think one can replace:
> 
>  exp2:
>   if (!isdigit (c))
>     {
>       if (c == 'i' || c == 'I' || c == 'n' || c == 'N')
>         goto inf_nan;
>       else
>         goto bad;
>     }
> 
> by

Done.  I forgot this was in two places.

> 
>  exp2:
>   if (!isdigit (c))
>     goto bad;
> 
> I changed this in my original Inf/NaN patch to the upper version, but
> you correctly remarked that it does not make much sense to have it for
> exp2. (But I forgot to change it back when I checked the patch in.) You
> can undo my change if you want.

Thanks for review.  I will commit after the above changes and retest.

Jerry

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-12-16 15:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-16  3:32 [patch, libfortran] PR34427 namelist input of inf-nan Jerry DeLisle
2007-12-16  3:33 ` Jerry DeLisle
2007-12-16  6:48 ` H.J. Lu
2007-12-16 14:32 ` Tobias Burnus
2007-12-16 15:53   ` Jerry DeLisle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).