chiark / gitweb /
sort-badblocks: Another handy testing utility.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 19 Feb 2022 11:54:20 +0000 (11:54 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 19 Feb 2022 11:55:20 +0000 (11:55 +0000)
sort-badblocks [new file with mode: 0755]

diff --git a/sort-badblocks b/sort-badblocks
new file mode 100755 (executable)
index 0000000..4826c38
--- /dev/null
@@ -0,0 +1,49 @@
+#! /usr/bin/perl
+
+use autodie;
+use Getopt::Std;
+
+(my $PROG = $0) =~ s!^.*/!!;
+sub usage (;\*) {
+  my ($f) = @_;
+  $f //= \*STDOUT;
+  print STDOUT "usage: $PROG [-r LO-HI] FILE ...\n";
+}
+
+my ($lo_bound, $hi_bound) = (undef, undef);
+my $bogus = 0;
+my %opt; $bogus = 1 unless getopts("r:", \%opt);
+if (defined $opt{"r"}) {
+  if ($opt{"r"} =~ /^(\d+)?-(\d+)?$/) { ($lo_bound, $hi_bound) = ($1, $2); }
+  else { $bogus = 1; }
+}
+if ($bogus) { usage STDERR; exit 2; }
+$lo_bound //= 0;
+
+my @bad;
+
+LINE: while (<>) {
+  chomp; s/\s*\#.*$//; next LINE if /^$/;
+  die "bad line" unless /^\s*(\d+)\s*(\d+)\s*$/;
+  my ($lo, $hi) = ($1, $2);
+  push @bad, [$lo, $hi];
+}
+
+@bad = sort { $a->[0] <=> $b->[0] } @bad;
+my ($lo, $hi) = (undef, undef);
+sub emit ($$) {
+  my ($lo, $hi) = @_;
+  if ($hi <= $lo_bound) { return; }
+  if (defined $hi_bound && $lo >= $hi_bound) { return; }
+  if ($lo < $lo_bound) { $lo = $lo_bound; }
+  if (defined $hi_bound && $hi > $hi_bound) { $hi = $hi_bound; }
+  printf "%d %d\n", $lo - $lo_bound, $hi - $lo_bound;
+}
+for my $item (@bad) {
+  my ($a, $b) = @$item;
+  if (!defined $lo) { ($lo, $hi) = ($a, $b); }
+  elsif ($a > $hi) { emit $lo, $hi; ($lo, $hi) = ($a, $b); }
+  elsif ($b < $lo) { die "buggy piece of shit"; }
+  else { $hi = $b; }
+}
+emit $lo, $hi if defined $lo;