Subject: | Calling dos2unix() on unix format file wipes it |
Both dos2unix() and unix2dos() use "&& print" and so only print out a
line if the s/// was successful.
I discovered that this causes it to fail (resulting in a 0 byte file) if
you call dos2unix() on a file that already uses unix EOL characters as
there is no \r\n sequence, so the print fails. Similarly calling
unix2dos() on a DOS file breaks it because \n => \r\n, so the DOS \r\n
becomes \r\n\n.
I was doing this because I didn't know if the file was DOS (likely) or
unix so wanted a way to use dos2unix(). Without the attached patch I
would have to open up the file and look at the EOL sequence at which
point I may as well just parse it myself anyway. The patch lets you call
the subs without fear that your file contents will be deleted.
I also added two test suite test files to confirm that the patch makes
things work as expected.
Thanks!
Subject: | 01-core.t |
#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 3;
use File::Temp;
my @words = (qw(Test File Format), '');
my $UNIX_TEST_STRING = join("\n", @words);
my $DOS_TEST_STRING = join("\r\n", @words);
use_ok('unix2dos');
local($,, $\, $/);
my($out, $tmpfile) = File::Temp::mkstemp('unix2dostest-XXXXX');
print $out $UNIX_TEST_STRING;
close($out);
unix2dos::unix2dos($tmpfile);
open(my $IN, '<', $tmpfile)
|| die "Error reopening temp file: $!\n";
my $dataIn = <$IN>;
close($IN);
is($dataIn, $DOS_TEST_STRING, 'Converted unix2dos');
unix2dos::dos2unix($tmpfile);
open($IN, '<', $tmpfile)
|| die "Error reopening temp file: $!\n";
$dataIn = <$IN>;
close($IN);
is($dataIn, $UNIX_TEST_STRING, 'Converted dos2unix');
unlink($tmpfile);
1;
# vim: set foldmethod=marker filetype=perl:
Subject: | unix2dos.patch |
--- lib/unix2dos.pm.orig 2012-04-10 13:42:17.993658534 -0400
+++ lib/unix2dos.pm 2012-04-11 09:08:23.042650509 -0400
@@ -48,7 +48,10 @@
local ( $^I , @ARGV ) = ( defined , @_ ) ;
- s/\n/\r\n/ && print while <>
+ while(<>) {
+ s/([^\r])\n/$1\r\n/mg;
+ print;
+ }
}
=head2 dos2unix
@@ -62,7 +65,10 @@
local ( $^I , @ARGV ) = ( defined , @_ ) ;
- s/\r\n/\n/ && print while <>
+ while(<>) {
+ s/\r\n/\n/mg;
+ print;
+ }
}
Subject: | 02-sameformat.t |
#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 4;
use File::Temp;
my @words = (qw(Test File Format), '');
my $UNIX_TEST_STRING = join("\n", @words);
my $DOS_TEST_STRING = join("\r\n", @words);
use_ok('unix2dos');
# diag('Ensure dos2unix on Unix CRLF file leaves it unchanged');
local($,, $\, $/);
my($out, $tmpfile) = File::Temp::mkstemp('unix2dostest-XXXXX');
print $out $UNIX_TEST_STRING;
close($out);
unix2dos::dos2unix($tmpfile);
open(my $IN, '<', $tmpfile)
|| die "Error reopening temp file: $!\n";
my $dataIn = <$IN>;
close($IN);
unlink($tmpfile);
is($dataIn, $UNIX_TEST_STRING, 'dos2unix did not change unix file');
# diag('Ensure unix2dos on DOS CRLF file leaves it unchanged');
($out, $tmpfile) = File::Temp::mkstemp('unix2dostest-XXXXX');
print $out $DOS_TEST_STRING;
close($out);
unix2dos::unix2dos($tmpfile);
open($IN, '<', $tmpfile)
|| die "Error reopening temp file: $!\n";
$dataIn = <$IN>;
close($IN);
unlink($tmpfile);
is($dataIn, $DOS_TEST_STRING, 'unix2dos did not change unix file');
my $DOS_TEST_STRING_WITH_BLANK_LINES = join(("\r\n" x 2), @words);
# unix2dos changes \n to \r\n.
# But if we give it \r\n endings it should not map to \r\r\n
local($,, $\, $/);
($out, $tmpfile) = File::Temp::mkstemp('unix2dostest-XXXXX');
print $out $DOS_TEST_STRING_WITH_BLANK_LINES;
close($out);
unix2dos::unix2dos($tmpfile);
open($IN, '<', $tmpfile)
|| die "Error reopening temp file: $!\n";
$dataIn = <$IN>;
close($IN);
unlink($tmpfile);
is(
$dataIn,
$DOS_TEST_STRING_WITH_BLANK_LINES,
'unix2dos correctly handles blank lines'
);
1;
# vim: set foldmethod=marker filetype=perl: