This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
d61bbff3a2e3ce120c691efa1b33bffe039d80aa
[perl5.git] / t / pod / testcmp.pl
1 package TestCompare;
2
3 use vars qw(@ISA @EXPORT $MYPKG);
4 #use strict;
5 #use diagnostics;
6 use Carp;
7 use Exporter;
8 use File::Basename;
9 use File::Spec;
10
11 @ISA = qw(Exporter);
12 @EXPORT = qw(&testcmp);
13 $MYPKG = eval { (caller)[0] };
14
15 ##--------------------------------------------------------------------------
16
17 =head1 NAME
18
19 testcmp -- compare two files line-by-line
20
21 =head1 SYNOPSIS
22
23     $is_diff = testcmp($file1, $file2);
24
25 or
26
27     $is_diff = testcmp({-cmplines => \&mycmp}, $file1, $file2);
28
29 =head2 DESCRIPTION
30
31 Compare two text files line-by-line and return 0 if they are the
32 same, 1 if they differ. Each of $file1 and $file2 may be a filenames,
33 or a filehandles (in which case it must already be open for reading).
34
35 If the first argument is a hashref, then the B<-cmplines> key in the
36 hash may have a subroutine reference as its corresponding value.
37 The referenced user-defined subroutine should be a line-comparator
38 function that takes two pre-chomped text-lines as its arguments
39 (the first is from $file1 and the second is from $file2). It should
40 return 0 if it considers the two lines equivalent, and non-zero
41 otherwise.
42
43 =cut
44
45 ##--------------------------------------------------------------------------
46
47 sub testcmp( $ $ ; $) {
48    my %opts = ref($_[0]) eq 'HASH' ? %{shift()} : ();
49    my ($file1, $file2) = @_;
50    my ($fh1, $fh2) = ($file1, $file2);
51    unless (ref $fh1) {
52       $fh1 = FileHandle->new($file1, "r") or die "Can't open $file1: $!";
53    }
54    unless (ref $fh2) {
55       $fh2 = FileHandle->new($file2, "r") or die "Can't open $file2: $!";
56    }
57   
58    my $cmplines = $opts{'-cmplines'} || undef;
59    my ($f1text, $f2text) = ("", "");
60    my ($line, $diffs)    = (0, 0);
61   
62    while ( defined($f1text) and defined($f2text) ) {
63       defined($f1text = <$fh1>)  and  chomp($f1text);
64       defined($f2text = <$fh2>)  and  chomp($f2text);
65       ++$line;
66       last unless ( defined($f1text) and defined($f2text) );
67       $diffs = (ref $cmplines) ? &$cmplines($f1text, $f2text)
68                                : ($f1text ne $f2text);
69       last if $diffs;
70    }
71    close($fh1) unless (ref $file1);
72    close($fh2) unless (ref $file2);
73   
74    $diffs = 1  if (defined($f1text) or defined($f2text));
75    if ( defined($f1text) and defined($f2text) ) {
76       ## these two lines must be different
77       warn "$file1 and $file2 differ at line $line\n";
78    }
79    elsif (defined($f1text)  and  (! defined($f1text))) {
80       ## file1 must be shorter
81       warn "$file1 is shorter than $file2\n";
82    }
83    elsif (defined $f2text) {
84       ## file2 must be longer
85       warn "$file1 is shorter than $file2\n";
86    }
87    return $diffs;
88 }
89
90 1;