1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
package File::Compare;
use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $Too_Big *FROM *TO);
require Exporter;
use Carp;
use UNIVERSAL qw(isa);
$VERSION = '1.1';
@ISA = qw(Exporter);
@EXPORT = qw(compare);
@EXPORT_OK = qw(cmp);
$Too_Big = 1024 * 1024 * 2;
sub VERSION {
# Version of File::Compare
return $File::Compare::VERSION;
}
sub compare {
croak("Usage: compare( file1, file2 [, buffersize]) ")
unless(@_ == 2 || @_ == 3);
my $from = shift;
my $to = shift;
my $closefrom=0;
my $closeto=0;
my ($size, $status, $fr, $tr, $fbuf, $tbuf);
local(*FROM, *TO);
local($\) = '';
croak("from undefined") unless (defined $from);
croak("to undefined") unless (defined $to);
if (ref($from) && (isa($from,'GLOB') || isa($from,'IO::Handle'))) {
*FROM = *$from;
} elsif (ref(\$from) eq 'GLOB') {
*FROM = $from;
} else {
open(FROM,"<$from") or goto fail_open1;
binmode FROM;
$closefrom = 1;
}
if (ref($to) && (isa($to,'GLOB') || isa($to,'IO::Handle'))) {
*TO = *$to;
} elsif (ref(\$to) eq 'GLOB') {
*TO = $to;
} else {
open(TO,"<$to") or goto fail_open2;
binmode TO;
$closeto = 1;
}
if (@_) {
$size = shift(@_) + 0;
croak("Bad buffer size for compare: $size\n") unless ($size > 0);
} else {
$size = -s FROM;
$size = 1024 if ($size < 512);
$size = $Too_Big if ($size > $Too_Big);
}
$fbuf = '';
$tbuf = '';
while(defined($fr = read(FROM,$fbuf,$size)) && $fr > 0) {
unless (defined($tr = read(TO,$tbuf,$fr)) and $tbuf eq $fbuf) {
goto fail_inner;
}
}
goto fail_inner if (defined($tr = read(TO,$tbuf,$size)) && $tr > 0);
close(TO) || goto fail_open2 if $closeto;
close(FROM) || goto fail_open1 if $closefrom;
return 0;
# All of these contortions try to preserve error messages...
fail_inner:
close(TO) || goto fail_open2 if $closeto;
close(FROM) || goto fail_open1 if $closefrom;
return 1;
fail_open2:
if ($closefrom) {
$status = $!;
$! = 0;
close FROM;
$! = $status unless $!;
}
fail_open1:
return -1;
}
*cmp = \&compare;
1;
__END__
=head1 NAME
File::Compare - Compare files or filehandles
=head1 SYNOPSIS
use File::Compare;
if (compare("file1","file2") == 0) {
print "They're equal\n";
}
=head1 DESCRIPTION
The File::Compare::compare function compares the contents of two
sources, each of which can be a file or a file handle. It is exported
from File::Compare by default.
File::Compare::cmp is a synonym for File::Compare::compare. It is
exported from File::Compare only by request.
=head1 RETURN
File::Compare::compare return 0 if the files are equal, 1 if the
files are unequal, or -1 if an error was encountered.
=head1 AUTHOR
File::Compare was written by Nick Ing-Simmons.
Its original documentation was written by Chip Salzenberg.
=cut
|