| 1 | #! /usr/bin/perl |
| 2 | |
| 3 | use autodie; |
| 4 | use Getopt::Std; |
| 5 | |
| 6 | (my $PROG = $0) =~ s!^.*/!!; |
| 7 | sub usage (;\*) { |
| 8 | my ($f) = @_; |
| 9 | $f //= \*STDOUT; |
| 10 | print STDOUT "usage: $PROG [-r LO-HI] FILE ...\n"; |
| 11 | } |
| 12 | |
| 13 | my ($lo_bound, $hi_bound) = (undef, undef); |
| 14 | my $bogus = 0; |
| 15 | my %opt; $bogus = 1 unless getopts("r:", \%opt); |
| 16 | if (defined $opt{"r"}) { |
| 17 | if ($opt{"r"} =~ /^(\d+)?-(\d+)?$/) { ($lo_bound, $hi_bound) = ($1, $2); } |
| 18 | else { $bogus = 1; } |
| 19 | } |
| 20 | if ($bogus) { usage STDERR; exit 2; } |
| 21 | $lo_bound //= 0; |
| 22 | |
| 23 | my @bad; |
| 24 | |
| 25 | LINE: while (<>) { |
| 26 | chomp; s/\s*\#.*$//; next LINE if /^$/; |
| 27 | die "bad line" unless /^\s*(\d+)\s*(\d+)\s*$/; |
| 28 | my ($lo, $hi) = ($1, $2); |
| 29 | push @bad, [$lo, $hi]; |
| 30 | } |
| 31 | |
| 32 | @bad = sort { $a->[0] <=> $b->[0] } @bad; |
| 33 | my ($lo, $hi) = (undef, undef); |
| 34 | sub emit ($$) { |
| 35 | my ($lo, $hi) = @_; |
| 36 | if ($hi <= $lo_bound) { return; } |
| 37 | if (defined $hi_bound && $lo >= $hi_bound) { return; } |
| 38 | if ($lo < $lo_bound) { $lo = $lo_bound; } |
| 39 | if (defined $hi_bound && $hi > $hi_bound) { $hi = $hi_bound; } |
| 40 | printf "%d %d\n", $lo - $lo_bound, $hi - $lo_bound; |
| 41 | } |
| 42 | for my $item (@bad) { |
| 43 | my ($a, $b) = @$item; |
| 44 | if (!defined $lo) { ($lo, $hi) = ($a, $b); } |
| 45 | elsif ($a > $hi) { emit $lo, $hi; ($lo, $hi) = ($a, $b); } |
| 46 | elsif ($b < $lo) { die "buggy piece of shit"; } |
| 47 | else { $hi = $b; } |
| 48 | } |
| 49 | emit $lo, $hi if defined $lo; |