Bug 29277

Summary: Formated stream output: Translate "\n" / achar(10) into "\r\n" on some platforms
Product: gcc Reporter: tobias.burnus
Component: fortranAssignee: Jerry DeLisle <jvdelisle2>
Status: RESOLVED FIXED    
Severity: enhancement CC: gcc-bugs
Priority: P3    
Version: 4.2.0   
Target Milestone: 4.2.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2006-10-04 05:28:37
Attachments: Preliminaey patch for STREAM formatted read.

Description tobias.burnus 2006-09-28 22:39:20 UTC
See http://gcc.gnu.org/ml/fortran/2006-09/msg00415.html

Brooks Moses wrote:

when a file is connected for stream access, the runtime library could very easily do a s/\n/\r\n/ on the output stream before writing it to the file. In fact, if we consider \r\n to be a record marker (on a given system), and we do wish to implement the behavior described in this paragraph [10.6.3] then it would be required to do so.

Actually, now that I read section 9.2.2.3 (and particularly note 9.9) on the Fortran 2003 Standard, I'm pretty sure it was the intent of the standard committee that this sort of substitution be done. Note 9.9 states:

    There may be some character positions in the file that do not correspond
    to characters written; this is because on some processors a record
    marker may be written to the file as a carriage-return/linefeed
    or other sequence. The means of determining the position in a file
    connected for stream access is via the POS= specifier in an INQUIRE
    statement (9.9.1.21).

Note, in particular, that this whole matter only applies to _formatted_ stream files -- that is, files which are expected to contain human-readable text that could be edited in a text editor. For unformatted stream files -- which are the only ones that should be containing "binary" data that would be corrupted by the substitution -- this doesn't apply, and no substitution would be made.

Thus, I think it's pretty clear that NEW_LINE should return ACHAR(10), and that for formatted stream-access files, the runtime library should convert that character to the appropriate system-specific line-ending string when writing to files. (This substitution would not be a regression against g77, because files opened for stream access do not exist in g77 code, and the substitution would not be made for non-stream files.)
Comment 1 Jerry DeLisle 2006-09-28 23:23:30 UTC
Please note that with formatted stream I/O we implicitly write a /n or /r/n in the next_record_w () function in transfer.c depending on the system.  I think this meets the intent.

Now an issue I see is what if we want to explicitly write a /n on this system?  There would be no way to do that if we translate it to /n/r.  I am not sure the intent of the committee was to restrict this in this way, but allow it in the case of formatted end of record.

I have not tried this, but if I write out a formatted string with one character /n I wonder if we we get /n/r/n with current gfortran.  

I am not agreeing or diagreeing here.  You have raised a good question here.
Comment 2 Jerry DeLisle 2006-09-28 23:36:55 UTC
Another thought occurs to me.  With formatted stream I/O the newline is handled automatically for the user.  However, there is nothing to say someone would not want to use unformatted stream I/O to write human readable files.  In that case, you would want the result of newline to give the /r/n or /n on the respective systems.

Based on this thinking, the translation, if any, should be done for unformatted I/O and only when the NEWLINE function is explicitly used.

Clealy we have a case where the standard may not be all that clear.
Comment 3 Jerry DeLisle 2006-10-04 05:28:37 UTC
OK, I confess I sen a note to Richard Maine to doble check on this.  Brooks has it absolutely right.  So, I will see what I can come up with for you.  If its a requirement of the standard, it is not an enhancement.
Comment 4 Jerry DeLisle 2006-10-04 06:28:37 UTC
Oops.  This is F2003 issue and therfore an enhancement relative to F95.
Comment 5 Jerry DeLisle 2006-10-09 03:07:16 UTC
Created attachment 12398 [details]
Preliminaey patch for STREAM formatted read.

There is a related problem with formatted stream read:

program stream
    implicit none
    character(len=50) :: r1,r2
    open(10,file='test.dat',form='formatted',access='stream',status='old')
    read(10,'(a)') r1
    read(10,'(a)') r2
    print *, ':',trim(r1),':'
    print *, ':',trim(r2),':'
end program stream

I have a preliminary patch for this that I would appreciate some testing on cygwin or other CR-LF type system.  This is for the read only.
Comment 6 Jerry DeLisle 2006-10-09 03:38:56 UTC
I expect the test case streamio_4.f90 to fail with the preliminary patch.  I have not completed the formatted stream write portion.  What I need confirmed is that when reading that the file is being positioned correctly when a CR-LF is encountered.
Comment 7 patchapp@dberlin.org 2006-10-13 01:30:26 UTC
Subject: Bug number PR29277

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00677.html
Comment 8 Jerry DeLisle 2006-10-13 01:41:25 UTC
Note: I believe it may be necessary to explicitly inject a '\r' when a '\n' is embedded in a string. I am not quite set up to test this yet here.  So I would much appreciate if some one can do that, while I continue to study that part.  The patch submitted in comment #7 is fully test on '\n' only system.
Comment 9 Jerry DeLisle 2006-10-18 04:04:21 UTC
Subject: Bug 29277

Author: jvdelisle
Date: Wed Oct 18 04:04:07 2006
New Revision: 117846

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117846
Log:
2006-10-17  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/29277
	* io/list_read.c (next_char): Update strm_pos.
	(eat_separator): Delete extra call to unget_char.
	* io/transfer.c (read_block): Use read_sf for formatted stream I/O.
	(next_record_r): Update strm_pos for formatted stream I/O and handle
	end-of-record correctly.
	(next_record_w): Ditto.
	(next_record): Enable next record (r/w) functions and update strm_pos.
	(finalize_transfer): Call next_record to finish the record.

Modified:
    trunk/libgfortran/ChangeLog
    trunk/libgfortran/io/list_read.c
    trunk/libgfortran/io/transfer.c

Comment 10 Jerry DeLisle 2006-10-18 04:08:41 UTC
Subject: Bug 29277

Author: jvdelisle
Date: Wed Oct 18 04:08:30 2006
New Revision: 117847

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117847
Log:
2006-10-17  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/29277
	* gfortran.dg/streamio_4.f90: Update test.
	* gfortran.dg/streamio_11.f90: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/streamio_11.f90
Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/streamio_4.f90

Comment 11 Jerry DeLisle 2006-10-18 06:03:41 UTC
There is one final patch to go before closing this PR.  I am testing it now and developing a test case.  This is the part that converts LF to CR-LF for FORMATTED STREAM IO on those systems that #define HAVE_CRLF.

Comment 12 patchapp@dberlin.org 2006-10-18 07:01:12 UTC
Subject: Bug number PR29277

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00887.html
Comment 13 Jerry DeLisle 2006-10-18 23:13:41 UTC
Subject: Bug 29277

Author: jvdelisle
Date: Wed Oct 18 23:13:33 2006
New Revision: 117866

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117866
Log:
2006-10-18  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/29277
	* io/write.c (write_a): Add conversion of LF to CR-LF for systems with
	#define HAVE_CRLF.

Modified:
    trunk/libgfortran/ChangeLog
    trunk/libgfortran/io/write.c

Comment 14 Jerry DeLisle 2006-10-18 23:23:57 UTC
Fixed on 4.2.