home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / MPW / SpiderWEB / FixupMPWSymbols < prev   
Encoding:
Text File  |  1993-03-20  |  5.1 KB  |  218 lines  |  [TEXT/MPS ]

  1. Perl -s -Sx "{0}" {"Parameters"}
  2. Exit
  3.  
  4. #!/usr/local/bin/perl
  5.  
  6. @RecordSizes = (
  7.         1,    "Pad",
  8.         4,    "First",
  9.         2,    "Last",
  10.         0,    "Comment",
  11.         0,    "Dictionary",
  12.         6,    "Module",
  13.         8,    "Entry Point",
  14.         6,    "Size",
  15.         0,    "Contents",
  16.         0,    "Reference",
  17.         0,    "Computed Reference",
  18.         8,    "Filename",
  19.         0,    "Source Statement",
  20.         0,    "Module Begin",
  21.         8,    "Module End",
  22.         0,    "Block Begin",
  23.       12,    "Block End",
  24.        0,    "LocalID",
  25.         0,    "Local Label",
  26.         0,    "Local Type"
  27. );
  28.  
  29. $* = 1;
  30.  
  31. push(ARGV, "-") if ($#ARGV == -1);
  32.     
  33. while ($file = shift @ARGV) {
  34.     (($basename,$extension) = ($file =~ /^(.+)\.([^:]+)\.o$/)) 
  35.         || die "Failed to parse filename \"$file\""; 
  36.     
  37.     print STDERR "Processing $basename.web -> $basename.$extension -> $file\n" 
  38.         if ($debug);
  39.         
  40.     @web2offs = (0);
  41.     @webline  = ("");
  42.     $pos = 0;
  43.  
  44.     open(INPUT, "<$basename.web")
  45.         || die "Couldn't open \"$basename.web\" for reading.";    
  46.     
  47.     while (<INPUT>)  {
  48.         push(@web2offs, $pos);
  49.         push(@webline, $_);
  50.         $pos += length($_);
  51.     }    
  52.     
  53.     close(INPUT);
  54.     
  55.     open(INPUT, "<$basename.$extension")
  56.         || die "Couldn't open \"$basename.$extension\" for reading.";
  57.  
  58.     @src2web = ();
  59.     $pos = 0;
  60.     @source = ();
  61.     while (<INPUT>) {
  62.         if (/^#line\s+(\d+)/) {
  63.             push(@src2web, $pos, $1);
  64.         }
  65.         $pos += length($_);
  66.     }
  67.     
  68.     seek(INPUT,0,0);
  69.     while (read(INPUT,$source,1024)) {
  70.         push(@source, $source);
  71.     }
  72.     
  73.     close(INPUT);
  74.     
  75.     die "No #line directives for \"$file\"." if ($#src2web == -1);
  76.     
  77.     open(INPUT, "<$file") 
  78.         || die "Couldn't open \"$file\" for reading.";
  79.     open(OUTPUT,">$basename.fix.o") 
  80.         || die "Couldn't open \"$basename.fix.o\" for writing.";
  81.     
  82.     $pos = 0;
  83.     $curchunk = -1;
  84.     until (eof(INPUT)) {
  85.         read(INPUT, $tag, 1);
  86.         if (ord($tag) == 12)    {    # Source statement record
  87.             print STDERR "   Processing source record:\n" if ($debug);
  88.             
  89.             read(INPUT, $flags, 1);
  90.             read(INPUT, $size, 2);
  91.             read(INPUT, $junk, 4);
  92.             read(INPUT, $fileoffset, (ord($flags) & 128) ? 2 : 4);
  93.             read(INPUT, $codeoffset, (ord($flags) &  64) ? 2 : 4);
  94.             
  95.             ($size)        = unpack("S", $size);
  96.             $fileoffset    = unpack((ord($flags) & 128) ? "S" : "L", $fileoffset);
  97.             $codeoffset    = unpack((ord($flags) &  64) ? "S" : "L", $codeoffset);
  98.             $size            = $size    - 8 
  99.                                         - ((ord($flags) & 128) ? 2 : 4) 
  100.                                         - ((ord($flags) &  64) ? 2 : 4);
  101.             
  102.             @offsets = ();
  103.             
  104.             until (eof(INPUT)) {
  105.                 $pos += 2 while ($pos+2 <= $#src2web && $fileoffset >= $src2web[$pos+2]); 
  106.                 $pos -= 2 while ($pos-2 >= 0         && $fileoffset < $src2web[$pos]); 
  107.                 
  108.                 if ($curchunk != $src2web[$pos+1]) {
  109.                     $curchunk = $src2web[$pos+1];
  110.                     $curline  = $curchunk;
  111.                 }
  112.             
  113.                 ($blk,$off) = (($fileoffset-1) >> 10, ($fileoffset-1) & 1023);
  114.                 $source = substr($source[$blk] . $source[$blk+1], $off, 50);
  115.                 ($blk,$source) = $source =~ /^(.|\n)(.*)/;
  116.                 
  117.                 MATCH: 
  118.                     foreach $matchlen (10, 5, 2) {
  119.                         next if (length($source) < $matchlen && $matchlen > 2);
  120.                         $match = substr($source, 0, $matchlen);
  121.                         
  122.                         print STDERR "Trying to match: $match\n" if ($debug && $try);
  123.                         
  124.                         foreach $matchline (0, 1, -1, 2, 3, -2, 4, 5) {
  125.                             $off = index($webline[$curline+$matchline],$match);
  126.                             
  127.                             next if ($off == -1);
  128.                             next if ($blk eq "\n" 
  129.                                 && substr($webline[$curline+$matchline], 0, $off) !~ /^\s*$/);
  130.  
  131.                             $curline += $matchline;
  132.                             last MATCH;
  133.                         }
  134.                     }
  135.                 
  136.                 if ($debug) {
  137.                     printf STDERR "      %06d: %06d -> %06d\n", 
  138.                         $codeoffset,
  139.                         $fileoffset,
  140.                         $web2offs[$curline];
  141.                     
  142.                     if ($src) {
  143.                         print STDERR "         Src: $source\n";
  144.                         print STDERR "         Web: ", $webline[$curline];
  145.                     }
  146.                 }
  147.                 
  148.                 push(@offsets, $web2offs[$curline++], $codeoffset);
  149.                 
  150.                 last unless ($size > 0);
  151.                 
  152.                 $size -= 2;
  153.                 
  154.                 read(INPUT, $off, 2);
  155.                 ($blk,$off) = unpack("CC", $off);
  156.                 $fileoffset += $blk;
  157.                 $codeoffset += $off;
  158.             } 
  159.             
  160.             while ($#offsets > 0) {
  161.                 $fileoffset = shift @offsets;
  162.                 $codeoffset = shift @offsets;
  163.                 
  164.                 $out = $junk.pack("LL", $fileoffset+0, $codeoffset+0);
  165.                 DELTA:
  166.                     while (1) {
  167.                         ($lfo,$lco) = ($fileoffset,$codeoffset);
  168.                         last unless ($fileoffset = shift @offsets);
  169.                         last unless ($codeoffset = shift @offsets);
  170.                         
  171.                         if ($fileoffset < $lfo || $fileoffset-$lfo > 255 
  172.                          || $codeoffset < $lco || $codeoffset-$lco > 255
  173.                         ) {
  174.                             unshift(@offsets, $fileoffset, $codeoffset);
  175.                             
  176.                             last DELTA;
  177.                         }
  178.                         
  179.                         next if ($fileoffset == $lfo);
  180.                         
  181.                         $out .= pack("CC", $fileoffset-$lfo, $codeoffset-$lco);
  182.                     }
  183.                 
  184.                 print OUTPUT $tag, pack("CS", 0, length($out)+4), $out;
  185.             }
  186.         } else {
  187.             printf STDERR "   Processing %20s Size", $RecordSizes[2*ord($tag)+1] 
  188.                 if ($debug && $all);
  189.             
  190.             if ($size = $RecordSizes[2*ord($tag)]) {
  191.                 print STDERR $size, "\n" 
  192.                     if ($debug && $all);
  193.                     
  194.                 print OUTPUT $tag;
  195.                 --$size;
  196.             } else {
  197.                 print OUTPUT $tag;
  198.                 read(INPUT, $junk, 3);
  199.                 print OUTPUT $junk;
  200.                 ($size) = unpack("xS", $junk);
  201.                 
  202.                 print STDERR $size, "\n" 
  203.                     if ($debug && $all);
  204.                     
  205.                 $size -= 4;
  206.             }
  207.             if ($size) {
  208.                 read(INPUT, $junk, $size);
  209.                 print OUTPUT $junk;
  210.             }
  211.         }
  212.     }
  213.     
  214.     close(INPUT);
  215.     close(OUTPUT);
  216.     
  217.     &fsetfileinfo("MPS ", "OBJ ", "$basename.fix.o");
  218. }