1
0
mirror of git://projects.qi-hardware.com/wernermisc.git synced 2024-11-15 14:48:25 +02:00
wernermisc/bin/pidiff
Werner Almesberger 9a316150b4 bin/pidiff: position-independent diff filter
pidiff removes changes that merely move lines around from diff -u output.
The result is no longer a valid patch and is only intended for human use.
2012-04-23 19:32:33 -03:00

98 lines
1.7 KiB
Perl
Executable File

#!/usr/bin/perl
#
# pidiff - Position-independent diff filter
#
# Copyright 2012 by Werner Almesberger
#
# 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.
#
sub usage
{
print STDERR <<'EOF'
usage: diff -u ... | $0 [-n] [-D]
-n print line numbers
-D print debug output
EOF
;
exit(1);
}
while ($ARGV[0] =~ /^-/) {
if ($ARGV[0] eq "-n") {
$num = 1;
} elsif ($ARGV[0] eq "-D") {
$debug = 1;
} else {
&usage;
}
shift @ARGV;
}
$n = 0;
while (<>) {
$n++;
next unless /^[-+]/;
if (/^-/) {
push @{ $m{$'} }, $n;
} else {
push @{ $p{$'} }, $n;
}
}
for $k (keys %p) {
undef $bm, $mp;
undef $bd;
$em = $#{ $m{$k} };
$ep = $#{ $p{$k} };
$m = 0;
$p = 0;
while ($m <= $em && $p <= $ep) {
$d = abs($m{$k}[$m]-$p{$k}[$p]);
($bm, $bp, $bd) = ($m, $p, $d)
unless $d > $bd && defined $bd;
if ($m{$k}[$m] <= $p{$k}[$p] && $m < $em) {
$m++;
} else {
$p++;
}
}
# older variant, less efficient
# for $m (0..$#{ $m{$k} }) {
# for $p (0..$#{ $m{$k} }) {
# $d = abs($m{$k}[$m]-$p{$k}[$p]);
# ($bm, $bp, $bd) = ($m, $p, $d)
# unless $d > $bd && defined $bd;
# }
# }
next unless defined $bd;
if ($debug) {
chop($kk = $k);
print STDERR
"$kk: del m at $bm ($m{$k}[$bm]) p at $bp ($p{$k}[$bp])\n";
}
splice(@{ $m{$k} }, $bm, 1);
splice(@{ $p{$k} }, $bp, 1);
redo;
}
for $k (keys %m) {
for (@{ $m{$k} }) {
$l{$_} = "-$k";
}
}
for $k (keys %p) {
for (@{ $p{$k} }) {
$l{$_} = "+$k";
}
}
for (sort { $a <=> $b } keys %l) {
print "$_: " if $num;
print $l{$_};
}