92 lines
2.6 KiB
Perl
92 lines
2.6 KiB
Perl
package TestCompare;
|
|
|
|
use vars qw(@ISA @EXPORT $MYPKG);
|
|
#use strict;
|
|
#use diagnostics;
|
|
use Carp;
|
|
use Exporter;
|
|
use File::Basename;
|
|
use File::Spec;
|
|
use FileHandle;
|
|
|
|
@ISA = qw(Exporter);
|
|
@EXPORT = qw(&testcmp);
|
|
$MYPKG = eval { (caller)[0] };
|
|
|
|
##--------------------------------------------------------------------------
|
|
|
|
=head1 NAME
|
|
|
|
testcmp -- compare two files line-by-line
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
$is_diff = testcmp($file1, $file2);
|
|
|
|
or
|
|
|
|
$is_diff = testcmp({-cmplines => \&mycmp}, $file1, $file2);
|
|
|
|
=head2 DESCRIPTION
|
|
|
|
Compare two text files line-by-line and return 0 if they are the
|
|
same, 1 if they differ. Each of $file1 and $file2 may be a filenames,
|
|
or a filehandles (in which case it must already be open for reading).
|
|
|
|
If the first argument is a hashref, then the B<-cmplines> key in the
|
|
hash may have a subroutine reference as its corresponding value.
|
|
The referenced user-defined subroutine should be a line-comparator
|
|
function that takes two pre-chomped text-lines as its arguments
|
|
(the first is from $file1 and the second is from $file2). It should
|
|
return 0 if it considers the two lines equivalent, and non-zero
|
|
otherwise.
|
|
|
|
=cut
|
|
|
|
##--------------------------------------------------------------------------
|
|
|
|
sub testcmp( $ $ ; $) {
|
|
my %opts = ref($_[0]) eq 'HASH' ? %{shift()} : ();
|
|
my ($file1, $file2) = @_;
|
|
my ($fh1, $fh2) = ($file1, $file2);
|
|
unless (ref $fh1) {
|
|
$fh1 = FileHandle->new($file1, "r") or die "Can't open $file1: $!";
|
|
}
|
|
unless (ref $fh2) {
|
|
$fh2 = FileHandle->new($file2, "r") or die "Can't open $file2: $!";
|
|
}
|
|
|
|
my $cmplines = $opts{'-cmplines'} || undef;
|
|
my ($f1text, $f2text) = ("", "");
|
|
my ($line, $diffs) = (0, 0);
|
|
|
|
while ( defined($f1text) and defined($f2text) ) {
|
|
defined($f1text = <$fh1>) and chomp($f1text);
|
|
defined($f2text = <$fh2>) and chomp($f2text);
|
|
++$line;
|
|
last unless ( defined($f1text) and defined($f2text) );
|
|
$diffs = (ref $cmplines) ? &$cmplines($f1text, $f2text)
|
|
: ($f1text ne $f2text);
|
|
last if $diffs;
|
|
}
|
|
close($fh1) unless (ref $file1);
|
|
close($fh2) unless (ref $file2);
|
|
|
|
$diffs = 1 if (defined($f1text) or defined($f2text));
|
|
if ( defined($f1text) and defined($f2text) ) {
|
|
## these two lines must be different
|
|
warn "$file1 and $file2 differ at line $line\n";
|
|
}
|
|
elsif (defined($f1text) and (! defined($f1text))) {
|
|
## file1 must be shorter
|
|
warn "$file1 is shorter than $file2\n";
|
|
}
|
|
elsif (defined $f2text) {
|
|
## file2 must be longer
|
|
warn "$file1 is shorter than $file2\n";
|
|
}
|
|
return $diffs;
|
|
}
|
|
|
|
1;
|