diff --git a/bin/grepchunk b/bin/grepchunk new file mode 100755 index 0000000..3f13d75 --- /dev/null +++ b/bin/grepchunk @@ -0,0 +1,64 @@ +#!/usr/bin/perl + + +sub usage +{ + print STDERR "usage: $0 [-v] pattern [file ...]\n"; + exit(1); +} + + +if ($ARGV[0] eq "-v") { + $invert = 1; + shift @ARGV; +} +&usage if $ARGV[0] =~ /^-/; + +$pattern = shift @ARGV; +&usage unless defined $pattern; + + +sub flush +{ + my $mismatch = !($chunk =~ /$pattern/m); + + if ($mismatch == $invert) { + print $head; + print $chunk; + } + undef $head; + undef $chunk; +} + + +$HEAD = 0; +$CHUNK = 1; +$TAIL = 2; + + +$state = $HEAD; +while (<>) { + $state = $HEAD if /^diff /; + if (/^@@ -\d+,(\d+) \+\d+,(\d+)/) { + $state = $CHUNK; + ($in, $out) = ($1, $2); + $chunk = $_; + next; + } + if ($state == $HEAD) { + $head .= $_; + next; + } + next if $state == $TAIL; + $in-- if /^-/; + $out-- if /^\+/; + ($in--, $out--) if /^\s/; + die "in $in out $out" if $in < 0 || $out < 0; + if ($in+$out == 0) { + $state = $TAIL; + &flush; + } else { + $chunk .= $_; + } +} +&flush;