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] PR60148 Strings in NAMELIST do not honor DELIM= in open statement


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.


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