#!/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{$_}; }