ocr-tools/tools/bootstrap2.pl

73 lines
3.3 KiB
Perl

#!/usr/bin/env perl -s
#
# bootstrap2 -- Second stage bootstrapper, a version of unmunge
#
# $Id: bootstrap2,v 1.4 1997/11/14 03:52:54 mhw Exp $
sub Cleanup { close(IN); close(OUT); unlink(@files); @files = (); }
sub Fatal { &Cleanup(); print STDERR @_; exit(1); }
sub TabSkip { $tabWidth - 1 - (length($_[0]) % $tabWidth); }
sub TabFix { my ($needed, $actual) = (&TabSkip($_[0]), length($_[1]));
$tmp1 . ($tmp2 x $needed) . (" " x ($actual - $needed)); }
sub HumanEdit { my ($file, $line, @message) = ($inFile, @_); &Cleanup();
@old = stat($file); system($editor, "+$line", $file); @new = stat($file);
redo doFile if ($old[9] != $new[9]); # Check mod date
&Fatal("Line $line, ", @message); }
($tab,$yen,$pilc,$cdot,$tmp1,$tmp2)=("\244","\245","\266","\267","\377","\376");
$editor = $ENV{'VISUAL'} || $ENV{'EDITOR'} || 'vi';
($inFile, $manifest, @rest) = @ARGV;
if ($manifest ne "") { # Read manifest file
open(MANIFEST, "<$manifest") || &Fatal("$manifest: $!\n");
while (<MANIFEST>) { $dir = $1 if /^D\s+(.*)$/;
$index[$1] = $dir . $2 if /^(\d+)\s+(.*)$/; }
}
doFile: {
$seenPCRC = $pcrc1 = 0; $lastFlags = 1; $lastFileNum = 0;
open(IN, "<$inFile") || &Fatal("$inFile: $!\n");
for ($line = 1; ($_ = <IN>); $line++) {
s/^\s+//; s/\s+$//; # Strip leading and trailing spaces
next if (/^$/); # Ignore blank lines
($prefix, $seenCRCStr, $dummy, $_) = /^(\S{2})(\S{4})( (.*))?/;
while (s/$tab( *)/&TabFix($`, $1)/eo) {} # Correct spaces after tabs
s/($tmp2| )( +)/$1 . ($cdot x length($2))/ego; # Correct center dots
s/$tmp1/$tab/go; s/$tmp2/ /go; # Restore tabs/spaces from correction
s/\s*$/\n/; # Strip trailing spaces, and add a newline
$crc = 0; $pcrc = $pcrc1; # Calculate CRCs
for ($data = $_; $data ne ""; $data = substr($data, 1)) {
$crc ^= ord($data); $pcrc1 ^= ord($data);
for (1..8) { $crc = ($crc >> 1) ^ (($crc & 1) ? 0x8408 : 0);
$pcrc1 = ($pcrc1 >> 1) ^ (($pcrc1 & 1) ? 0xedb88320 : 0); }
}
($seenPLCRC, $seenCRC) = map { hex($_) } ($prefix, $seenCRCStr);
&HumanEdit($line, "CRC failed: $_") if $crc != $seenCRC;
if ($prefix eq '--') { # Process header line
&HumanEdit($line - 1, "Page CRC failed") if $pcrc != $seenPCRC;
($humanHdr, $pageNum, $file) = /^\S{19} (Page (\d+) of (.*))/;
($vers, $flags, $seenPCRC, $tabWidth, $prodNum, $fileNum) =
map { hex($_) } /^(\S)(\S\S)(\S{8})(\S)(\S{3})(\S{4})/;
if ($fileNum != $lastFileNum) {
print STDERR "MISSING files\n" if $fileNum != $lastFileNum + 1;
&Fatal("Missing pages\n") if $pageNum != 1 || !($lastFlags & 1);
if ($manifest ne "") {
($_ = $index[$fileNum]) =~ m%([^/]*)$%;
&Fatal("Manifest mismatch\n") if ($file ne $1);
($file = $_) =~ s|/+|mkdir($`, 0777), "/"|eg; # mkdir -p
}
&Fatal("$file: already exists\n") if (!$f && (-e $file));
close(OUT); open(OUT, ">$file") || &Fatal("$file: $!\n");
push(@files, $file); print "$fileNum $file\n";
} else {
&Fatal("MISSING pages\n") if ($pageNum != $lastPageNum + 1);
}
($lastFlags,$lastFileNum,$lastPageNum) = ($flags,$fileNum,$pageNum);
$pcrc1 = 0;
} else { # Unmunge normal line
&HumanEdit($line, "CRC failed: $_") if ($pcrc1 >> 24) != $seenPLCRC;
s/$tab( *)/"\t".(" " x (length($1) - &TabSkip($`)))/ego;
s/$yen\n/\f/o; s/$pilc\n//o; s/$cdot/ /go; print OUT;
}
}
}