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
|
#!/usr/bin/perl
use IO::File;
my @differ = qw(diff -bw);
my $oldtmp = "/tmp/difflog$$.old";
my $newtmp = "/tmp/difflog$$.new";
my $newfn = pop(@ARGV);
my $oldfn = pop(@ARGV);
my (%oldhash, %newhash);
read_file($newfn, \%newhash);
read_file($oldfn, \%oldhash);
my @oldentries = reverse sort keys %oldhash;
my @newentries = reverse sort keys %newhash;
my $old = 0;
my $new = 0;
while ($old < @oldentries && $new < @newentries)
{
my $cmp = $oldentries[$old] cmp $newentries[$new];
if ($cmp > 0)
{
printf("only in %s: %s\n\n", $oldfn, $oldentries[$old++]);
}
elsif ($cmp < 0)
{
printf("only in %s: %s\n\n", $newfn, $newentries[$new++]);
}
else
{
if ($oldhash{$oldentries[$old]} ne $newhash{$newentries[$new]}) {
my $oldfh = new IO::File("/tmp/difflog$$.old", 'w');
$oldfh->print($oldhash{$oldentries[$old]});
$oldfh->close();
my $newfh = new IO::File("/tmp/difflog$$.new", 'w');
$newfh->print($newhash{$newentries[$new]});
$newfh->close();
open(DIFF, join(' ', @differ, @ARGV, $oldtmp, $newtmp, '|'));
my @lines = <DIFF>;
close(DIFF);
unlink </tmp/difflog$$.*>;
if (@lines)
{
print "diff for ", $oldentries[$old], ":\n";
map {
s/$oldtmp/$oldfn/;
s/$newtmp/$newfn/;
} @lines;
print @lines, "\n";
}
}
++$old;
++$new;
}
}
while ($old < @oldentries)
{
printf("only in %s: %s\n", $oldfn, $oldentries[$old++]);
}
while ($new < @newentries)
{
printf("only in %s: %s\n", $newfn, $newentries[$new++]);
}
sub read_file
{
my $fn = shift;
my $hashref = shift;
my $fh = new IO::File($fn, 'r');
my ($tag, $date, $entry, $block);
my $attrib = q[(:?(:?workers?|users?)/)?\d+];
$attrib = q[(?:\w+\s+)*] . $attrib;
$attrib = q[(?:[^/]*\D:\s*)?] . $attrib;
$attrib = qq[(?:unposted|$attrib)];
$attrib = qq[(?:(?:$attrib,\\s*)*$attrib)];
$hashref->{unattributed} = $block = '';
while (my $line = $fh->getline())
{
if ($line =~ /(\d{4}-\d\d-\d\d)\s+.+\s+<.+\@.+>/i) {
$date = $1;
$block =~ s/\n*\Z/\n/;
if ($entry) {
$hashref->{$entry} .= "$tag\n$block";
} elsif ($tag) {
$hashref->{unattributed} .= "\n$tag$block";
}
$entry = $block = '';
$tag = $line;
} elsif ($line =~ /\* ((?:$attrib)[^:]*):/) {
my $next = $1;
if ($entry) {
$block =~ s/\n*\Z/\n/;
$hashref->{$entry} .= "$tag\n$block";
}
if (exists($hashref->{$next})) {
$hashref->{$next} .= "\n";
} else {
$hashref->{$next} = '';
}
$entry = $next;
$block = $line;
} else {
$block .= $line;
}
}
$fh->close();
}
|