[patch, libgfortran] PR60148 Strings in NAMELIST do not honor DELIM= in open statement
Tobias Burnus
burnus@net-b.de
Sun Mar 2 20:51:00 GMT 2014
Dear Jerry, hi all,
Jerry DeLisle wrote:
> The attached patch fixes this by actually implementing it. I cleaned up some of
> the code by getting rid of the tmp_delim variables and adding a "mode" to
> write_character which is used to ignore delimiters when writing out variable
> names and other namelist parts.
gfortran seems to be special as it defaults to printing the " (quote)
delimiter by default while other compilers seem to default to "none".
With the patch, gfortran distinguishes between "none" (i.e. no quote
character) and not set. When unset, gfortran continues to use the double
quote character for quotation and only with "none" is uses no quote
character.
I think gfortran's new behaviour is not not standard conform as the
standard states that DELIM= defaults to NONE. On
the other hand, the standard explicitly requires that on input the quote
characters have to be present.
Given that the current behaviour permits to read-back the namelist, I
think it is invalid but acceptable to default to DELIM=QUOTE. However, I
wonder whether we should document it at
gcc.gnu.org/onlinedocs/gfortran/Extensions-implemented-in-GNU-Fortran.html
> I will prepare a test case.
Thanks!
I think a side-effect of the patch is that the two cases below behave
now differently: The first returns "tue", the other causes an error.
Before, both caused errors - which matches the result with Cray ftn and
PGI pgf90. ifort on the other hand reads the string successfully (at
least when the string var is shorter than trailing white spaces at the
end of the string.)
program namelistout
implicit none
character :: mystring*3 = 'tue'
namelist /mylist/ mystring
open(unit=10, file='junk.dat')
write(10, '(A)') ' &mylist mystring=tue /'
close(10)
mystring = repeat('X', 10)
open(unit=10,file='junk.dat',delim='none')
read(10, mylist)
write(*, mylist)
close(10)
mystring = repeat('X', 10)
open(unit=10,file='junk.dat')
read(10, mylist)
write(*, mylist)
close(10)
end program
> Regression tested on x86_64.
> OK for trunk or hold for next stage?
The patch looks good to me with a test case. I think we should/could
document the special (nonstandard conforming) behaviour in the
documentation. Actually, we could also mention the extended array
support - i.e. "&nml array(1) =1,2,3,4 /" to read "array(1:4)" - but
also make clear that this is an extension and that it should be avoided.
From my side, I think it can still go into the trunk.
> +write_character (st_parameter_dt *dtp, const char *source, int kind, int length, int mode)
> {
> int i, extra;
> char *p, d;
>
> - switch (dtp->u.p.current_unit->delim_status)
> + if (mode)
I think it would be clearer to use "mode == DELIM"
Tobias
> 2014-03-01 Jerry DeLisle <jvdelisle@gcc.gnu>
>
> PR libfortran/60148
> * io/inquire.c (inquire_via_unit): In the case of
> DELIM_UNSPECIFIED set inquire return string to "NONE".
> * io/list_read.c (read_character): In the case of DELIM_NONE and
> namelists, complete the character read using the namelist
> variable length.
> * io/open.c (new_unit): Don't set delim status to none if not
> specified so that DELIM_UNSPECIFIED can be used later.
> * io/transfer.c (data_transfer_init): For namelist I/O, if the
> unit delim status is unspecified set the current status to quote.
> Otherwise, set current status to the unit status.
> * io/unit.c (get_internel_unit, init_unit): Remember to set
> flags_delim initially to DELIM_UNSPECIFIED so defaults come out
> correctly.
> * io/write.c (write_character): Add a new function argument
> "mode" to signify that raw output is to be used vs output with
> delimiters. If the mode is set to DELIM (1) proceed with
> delimiters. (list_formatted_write_scalar): Write the separator
> only if a delimiter was previously specified. Update the call to
> write_character with the mode argument given.
> (namelist_write_newline): Use the mode argument. (nml_write_obj):
> Use the mode argument. Remove use of tmp_delim. Write the
> semi-colon or comma correctly only when needed with using
> delimiters. Cleanup whitespace.
> (namelist_write): If delim is not specified in namelist I/O,
> default to using quotes. Get rid of the tmp_delim variable and
> use the new mode argument if write_character.
More information about the Fortran
mailing list