This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran 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]

[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

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