Root/bin/pidiff

1#!/usr/bin/perl
2#
3# pidiff - Position-independent diff filter
4#
5# Copyright 2012 by Werner Almesberger
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12
13
14sub usage
15{
16    print STDERR <<'EOF'
17usage: diff -u ... | $0 [-n] [-D]
18
19  -n print line numbers
20  -D print debug output
21EOF
22;
23    exit(1);
24}
25
26
27while ($ARGV[0] =~ /^-/) {
28    if ($ARGV[0] eq "-n") {
29        $num = 1;
30    } elsif ($ARGV[0] eq "-D") {
31        $debug = 1;
32    } else {
33        &usage;
34    }
35    shift @ARGV;
36}
37
38$n = 0;
39while (<>) {
40    $n++;
41    next unless /^[-+]/;
42    if (/^-/) {
43        push @{ $m{$'} }, $n;
44    } else {
45        push @{ $p{$'} }, $n;
46    }
47}
48for $k (keys %p) {
49    undef $bm, $mp;
50    undef $bd;
51    $em = $#{ $m{$k} };
52    $ep = $#{ $p{$k} };
53    $m = 0;
54    $p = 0;
55    while ($m <= $em && $p <= $ep) {
56        $d = abs($m{$k}[$m]-$p{$k}[$p]);
57        ($bm, $bp, $bd) = ($m, $p, $d)
58            unless $d > $bd && defined $bd;
59        if ($m{$k}[$m] <= $p{$k}[$p] && $m < $em) {
60            $m++;
61        } else {
62            $p++;
63        }
64    }
65# older variant, less efficient
66# for $m (0..$#{ $m{$k} }) {
67# for $p (0..$#{ $m{$k} }) {
68# $d = abs($m{$k}[$m]-$p{$k}[$p]);
69# ($bm, $bp, $bd) = ($m, $p, $d)
70# unless $d > $bd && defined $bd;
71# }
72# }
73    next unless defined $bd;
74    if ($debug) {
75        chop($kk = $k);
76        print STDERR
77            "$kk: del m at $bm ($m{$k}[$bm]) p at $bp ($p{$k}[$bp])\n";
78    }
79    splice(@{ $m{$k} }, $bm, 1);
80    splice(@{ $p{$k} }, $bp, 1);
81    redo;
82}
83
84for $k (keys %m) {
85    for (@{ $m{$k} }) {
86        $l{$_} = "-$k";
87    }
88}
89for $k (keys %p) {
90    for (@{ $p{$k} }) {
91        $l{$_} = "+$k";
92    }
93}
94for (sort { $a <=> $b } keys %l) {
95    print "$_: " if $num;
96    print $l{$_};
97}
98

Archive Download this file

Branches:
master



interactive