pjs/webtools/lxr/diff

207 строки
5.0 KiB
Perl
Executable File

#!/usr/bin/perl
# $Id: diff,v 1.2 2006-12-07 04:59:38 reed%reedloden.com Exp $
# diff -- Display diff output with markup.
#
# Arne Georg Gleditsch <argggh@ifi.uio.no>
# Per Kristian Gjermshus <pergj@ifi.uio.no>
#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
######################################################################
use lib 'lib/';
use SimpleParse;
use LXR::Common;
use LXR::Config;
use DB_File;
sub htmlsub {
my ($s, $l) = @_;
my @s = split(/(<[^>]*>|&[\#\w\d]+;?)/, $s);
$s = '';
while (@s) {
my $f = substr(shift(@s), 0, $l);
$l -= length($f);
$s .= $f;
$f = shift(@s);
if ($f =~ /^&/) {
if ($l > 0) {
$s .= $f;
$l--;
}
} else {
$s .= $f;
}
}
$s .= ' ' x $l;
return $s;
}
sub printdiff {
unless ($diffvar) {
foreach ($Conf->allvariables) {
push(@vars, $Conf->vardescription($_));
}
$vars[$#vars-1] .= " or ".pop(@vars) if $#vars > 0;
print("<p align=center>\n",
"Please indicate the version of the file you wish to\n",
"compare to by clicking on the appropriate\n",
join(", ",@vars)," button.\n",
"</p>\n");
return;
}
unless ($Path->{'file'}) {
print("<h3 align=center>Diff not yet supported for directories.</h3>\n");
return;
}
$origvirt = $Path->{'virt'}.$Path->{'file'};
$origreal = $Path->{'real'}.$Path->{'file'};
$origval = $Conf->variable($diffvar);
$Conf->variable($diffvar,$diffval);
$diffvirt = $Conf->mappath($Path->{'virt'}).$Path->{'file'};
$diffreal = $Conf->sourceroot.$diffvirt;
$Conf->variable($diffvar,$origval);
# print("<h3>Diff of $origvirt -> $diffvirt</h3>\n");
# print("<h3>($origreal -> $diffreal)</h3>\n");
# FIXME: Check existence of $origreal & $diffreal.
&fflush;
unless (open(DIFF, "-|")){
open(STDERR, ">&STDOUT");
exec('diff', '-U0', $origreal, $diffreal);
print "*** Diff subprocess died unexpextedly: $!\n";
exit;
}
while (<DIFF>) {
if (($os, $ol, $ns, $nl) =
/@@ -(\d+)(?:,(\d+)|) \+(\d+)(?:,(\d+)|) @@/) {
$os++ if $ol eq '0';
$ns++ if $nl eq '0';
$ol = 1 unless defined($ol);
$nl = 1 unless defined($nl);
$bo = $os + $ofs;
if ($ol < $nl) {
$ofs += $nl - $ol;
$dir = '&gt;&gt;';
$ms = $nl - $ol;
$ml = $ol;
$orig{$os+$ol} = $ms;
} else {
$dir = '&lt;&lt;';
$ms = $ol - $nl;
$ml = $nl;
$new{$ns+$nl} = $ms;
}
foreach (0..$ml - 1) {
$chg{$bo + $_} = '!!';
}
foreach (0..$ms - 1) {
$chg{$bo + $ml + $_} = $dir;
}
}
}
close(<DIFF>);
print("<h1>Diff markup</h1>\n",
"<h3>Differences between ",
&fileref("$origvirt <i>(".$Conf->vardescription($diffvar).
" $origval)</i>", $origvirt, undef, "$diffvar=$origval"),
" and ",
&fileref("$diffvirt <i>(".$Conf->vardescription($diffvar).
" $diffval)</i>",$diffvirt, undef, "$diffvar=$diffval"),
"</h3><hr>\n");
# "<table width=\"100%\" border=0 cellpadding=0><tr><td>",
#
# &fileref("<b>$origvirt <i>(".$Conf->vardescription($diffvar).
# " $origval)</i></b>", $origvirt, undef, "$diffvar=$origval"),
# "<hr></td>\n<td></td>\n<td>",
#
# &fileref("<b>$diffvirt <i>(".$Conf->vardescription($diffvar).
# " $diffval)</i></b>",$diffvirt, undef, "$diffvar=$diffval"),
# "<hr></td>\n</tr></table>\n");
open(FOO, $origreal);
$orig = '';
&markupfile(\*FOO, $Path->{'virt'}, $Path->{'file'},
sub { $orig .= shift });
$len = $.+$ofs;
close(FOO);
$Conf->variable($diffvar, $diffval);
open(FOO, $diffreal);
$new = '';
&markupfile(\*FOO, $Conf->mappath($Path->{'virt'}), $Path->{'file'},
sub { $new .= shift });
close(FOO);
$Conf->variable($diffvar, $origval);
$i = 1; $orig =~ s/^/"\n" x ($orig{$i++})/mge;
$i = 1; $new =~ s/^/"\n" x ($new{$i++})/mge;
@orig = split(/\n/, $orig);
@new = split(/\n/, $new);
print("<pre>");
foreach $i (0..$len) {
$o = &htmlsub($orig[$i], 50);
# $n = &htmlsub($new[$i], 999);
$n = $new[$i];
# print("<tr><td><code>$o</code></td>".
# "<td><font color=red> ", $chg{$i+1}, " </font></td>".
# "<td><code>$n</code></td></tr>\n");
print("$o <font color=red>", ($chg{$i+1} || " "), "</font> $n\n");
}
print("</pre>");
# print("</td></tr></table>");
}
($Conf, $HTTP, $Path) = &init;
$diffvar = $HTTP->{'param'}->{'diffvar'};
$diffval = $HTTP->{'param'}->{'diffval'};
&makeheader('diff');
&printdiff;
&makefooter('diff');