This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[patch, libgfortran] Final patch for PR29277, LF conversion to CR-LF
- From: Jerry DeLisle <jvdelisle at verizon dot net>
- To: Fortran List <fortran at gcc dot gnu dot org>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>, Danny Smith <dannysmith at clear dot net dot nz>, Brooks Moses <bmoses at stanford dot edu>
- Date: Tue, 17 Oct 2006 23:59:32 -0700
- Subject: [patch, libgfortran] Final patch for PR29277, LF conversion to CR-LF
:ADDPATCH fortran:
The attached patch implements requirements in F2003 10.6.3 regarding handling of
NEWLINE in FORMATTED STREAM I/O. The patch is fairly self explanatory. In
systems with #define HAVE_CRLF we must scan the string for instances of '\n' and
write out a '\r\n' instead.
The attached patch, of necessity, must write the string in chunks broken up by
any embedded '\n' characters.
I have regression tested this two ways. Without #define HAVE_CRLF which is
normal on my system (i686-linux) and with #define HAVE_CRLF manually inserted at
the top of transfer.c and write.c. Both cases pass regression testing.
Danny would you mind testing on mingw. Would someone offer to review this
please. In parallel, I will generate an additional test case. The attached
test case is an example for all to see. It gives interesting results, and I
believe it is correct.
OK for 4.2. I have an email to Mark Mitchell to make sure he is OK with
committing this, provided it gets a review.
Regards,
Jerry
2006-10-17 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/29277
* io/write.c (write_a): Add conversion of LF to LF-CR for systems with
#define HAVE_CRLF.
Index: io/write.c
===================================================================
*** io/write.c (revision 117845)
--- io/write.c (working copy)
*************** write_a (st_parameter_dt *dtp, const fno
*** 54,70 ****
wlen = f->u.string.length < 0 ? len : f->u.string.length;
! p = write_block (dtp, wlen);
! if (p == NULL)
! return;
! if (wlen < len)
! memcpy (p, source, wlen);
else
{
! memset (p, ' ', wlen - len);
! memcpy (p + wlen - len, source, len);
}
}
static GFC_INTEGER_LARGEST
--- 54,123 ----
wlen = f->u.string.length < 0 ? len : f->u.string.length;
! #ifdef HAVE_CRLF
! /* If this is formatted STREAM IO convert any embedded line feed characters
! to CR_LF on systems that use that sequence for newlines. See F2003
! Standard sections 10.6.3 and 9.9 for further information. */
! if (is_stream_io (dtp))
! {
! const char crlf[] = "\r\n";
! int i, q, bytes;
! q = bytes = 0;
!
! /* Write out any padding if needed. */
! if (len < wlen)
! {
! p = write_block (dtp, wlen - len);
! memset (p, ' ', wlen - len);
! }
!
! /* Scan the source string looking for '\n' and convert it if found. */
! for (i = 0; i < wlen; i++)
! {
! if (source[i] == '\n')
! {
! /* Write out the previously scanned characters in the string. */
! if (bytes > 0)
! {
! p = write_block (dtp, bytes);
! memcpy (p, &source[q], bytes);
! q += bytes;
! bytes = 0;
! }
!
! /* Write out the CR_LF sequence. */
! q++;
! p = write_block (dtp, 2);
! memcpy (p, crlf, 2);
! }
! else
! bytes++;
! }
! /* Write out any remaining bytes if no LF was found. */
! if (bytes > 0)
! {
! p = write_block (dtp, bytes);
! memcpy (p, &source[q], bytes);
! }
! }
else
{
! #endif
! p = write_block (dtp, wlen);
! if (p == NULL)
! return;
!
! if (wlen < len)
! memcpy (p, source, wlen);
! else
! {
! memset (p, ' ', wlen - len);
! memcpy (p + wlen - len, source, len);
! }
! #ifdef HAVE_CRLF
}
+ #endif
}
static GFC_INTEGER_LARGEST
program stream_test_short
implicit none
character(len=*), parameter :: rec1 = 'record1'
character(len=*), parameter :: rec2 = 'record2'
character(len=25) :: str3
open(10,file="lookatme.txt",form='formatted',access='stream')
write(10,'(a)') rec1//new_line('a')//new_line('a')//new_line('a')//new_line('a')
str3 = rec1//new_line('a')//new_line('a')//new_line('a')//new_line('a')//rec2
write(10,'(a15)') str3
close(10)
end program stream_test_short