home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / Perl / Non-RPC / !Perl / scripts / listalf < prev    next >
Text File  |  1998-07-14  |  5KB  |  176 lines

  1. #!perl -lw
  2. # Version 0.02
  3. # A perl version of Gareth's listalf.
  4. # Somewhat slower.
  5. # Considereably more hackable.
  6.  
  7. use strict;
  8. use RISCOS::Throwback;
  9. use RISCOS::File ':DEFAULT', '/glob/';
  10. use RISCOS::Filespec;
  11. use RISCOS::Chunkfile;
  12. use RISCOS::AOF;
  13. use RISCOS::ALF;
  14. use RISCOS::Time qw (time2utc time2local);
  15. # Keep paths intact (eg Unix:o.UnixLib
  16. glob_control (&fileglob_PrintOriginalPath);
  17.  
  18. use Getopt::Std;
  19.  
  20. use vars qw(%opt $VERSION);
  21.  
  22. $VERSION = 0.02;
  23. getopts ('?nmtsoyiclv', \%opt);
  24.  
  25. $opt{'m'}= $opt{'n'} = 1 unless keys (%opt);
  26.  
  27. sub do_file
  28. {
  29.     my $file = shift;
  30.     my $chunks = new RISCOS::Chunkfile shift;
  31.     my $entry = shift;
  32.     # So that name and data source can differ
  33.  
  34.     unless (defined $chunks) {
  35.     warn "'$file' is not a chunkfile";
  36.     }
  37.     elsif ($chunks->Lookup ('OBJ_HEAD'))
  38.     {
  39.     # izza AOF
  40.     warn "File '$file' is AOF\n";
  41.     }
  42.     elsif ($chunks->Lookup ('LIB_DIRY'))
  43.     {
  44.     if (my $library = new RISCOS::ALF $chunks) {
  45.         # izza ALF
  46.         if ($entry) {
  47.         &do_alf ($library, $file, $library->Dir_Lookup ($entry));
  48.         } else {
  49.         &do_alf ($library, $file, values %{$library->Dir});
  50.         }
  51.     }
  52.     }
  53.     else
  54.     {
  55.     warn "'$file' is not a recognised chunkfile - contains "
  56.       . join (', ', keys %{$chunks->Index}) . ' chunks';
  57.     }
  58. }
  59.  
  60. sub do_alf ($$;@) {
  61.     my $library = shift;
  62.     my $file = shift;
  63.     my $maxlen = 0;
  64.     my $maxoff = 0;
  65.     my $maxsize = 0;
  66.     my $formatnum = 1 + int (log (2 + scalar @_) / log 10);
  67.     my $count = 0;
  68.  
  69.     foreach (@_) {
  70.     my ($len, $size, $off) = (length $_->Name(), $_->Chunk()->Length(),
  71.                   $_->Chunk()->Offset());
  72.     $maxlen = $len if $len > $maxlen;
  73.     $maxsize = $size if $size > $maxsize;
  74.     $maxoff = $off if $off > $maxoff;
  75.     $count++;
  76.     }
  77.     if ($opt{'l'}) {
  78.     print "Library file '$file':";
  79.     print '  ALF version ', $library->Version;
  80.     print '  contents updated ', scalar time2local $library->Time->Time;
  81.     print '  symtable updated ', scalar time2local $library->Sym_Time->Time;
  82.     print '  ', $count, ' member', $count == 1 ? '' : 's';
  83.     print '-' x 60;
  84.     }
  85.     my $formatoff = 1 + int (log ($maxoff) / log 16);
  86.     my $formatsize = 1 + int (log ($maxsize) / log 10);
  87.  
  88.     foreach (sort {$a->Index() <=> $b->Index()} @_) {
  89.     # Reference to chunk data means "treat this as file to load"
  90.     my (@line, $size);
  91.     push @line, sprintf "%${formatnum}d", $_->Index() if $opt{'n'};
  92.     push @line, sprintf "%-${maxlen}s", $_->Name() if $opt{'m'};
  93.     if ($opt{'s'} or $opt{'o'}) {
  94.         my @so;
  95.         @so =
  96.           sprintf "%${formatsize}d", $_->Chunk->Length();
  97.         push @so,
  98.           sprintf "at &%0${formatoff}X", $_->Chunk->Offset();
  99.         push @line, join ' ', @so;
  100.     }
  101.     push @line, scalar time2local ($_->Time->Time) if $opt{'t'};
  102.  
  103.     if ($opt{'s'} or $opt{'i'} or $opt{'c'}) {
  104.         my $aof = new RISCOS::AOF \($_->Chunk->Data);
  105.         if ($aof) {
  106.         if ($opt{'c'}) {
  107.             my @symbols;
  108.             foreach my $symbol (@{$aof->Symbols}) {
  109.             push @symbols, $symbol->Name() if $symbol->Scope eq '';
  110.             }
  111.             print join ' : ', @line, (join ' ', @symbols);
  112.         } elsif ($opt{'i'}) {
  113.             foreach my $symbol (@{$aof->Symbols}) {
  114.             print join ' : ', @line, $symbol->Name()
  115.               if $symbol->Scope eq '';
  116.             }
  117.         } else {
  118.             print join ' : ', @line;
  119.             foreach my $symbol (@{$aof->Symbols}) {
  120.             print '       | ' . $symbol->Name()
  121.               if $symbol->Scope eq '';
  122.             }
  123.         }
  124.         } else {
  125.         warn 'Failed to extract symbols from ' . $_->Name();
  126.         print join ' : ', @line if @line;
  127.         }
  128.     } else {
  129.         print join ' : ', @line if @line;
  130.     }
  131. #    print "$file,", $_->Name(), ' : ', $_->Index();
  132.     
  133.     }
  134. }
  135.  
  136. if ($opt{'v'}) {
  137.     print STDERR "This is $0 version $VERSION";
  138.     exit;
  139. }
  140.  
  141. if ($opt{'?'}) {
  142.     print STDERR <<"!!";
  143. $0, version $VERSION
  144. Options:
  145.   -n --numbers     display chunk numbers
  146.   -m --members     display membernames
  147.   -t --timestamps  display timestamps of members
  148.   -s --sizes       display sizes of members
  149.   -o --offsets     display offsets of members within file
  150.   -y --symbols     display symbol table
  151.   -i --inline      display symbols on same line as other stuff
  152.   -c --compact     ditto, with all symbols on one line
  153.   -l --lib-info    display ALF version, library timestamp etc
  154.   -v --version     print version number of this program
  155.   If no options are given, -nm is assumed.
  156. !!
  157.   exit 0;
  158. }
  159. foreach (@ARGV)
  160. {
  161.     # Try to make the entry the longest comma free string possible
  162.     my ($file, $entry) = ($_);
  163.  
  164.     # Found a comma? If so separate as it's probably a $file,$entry for ALF
  165.     ($file, $entry) = /^(.*?),?([^,]*)$/ if tr/,//;
  166.  
  167.     my @files = glob ($file);
  168.  
  169.     @files = $file unless @files;    # Push pattern if unmatched
  170.  
  171.     foreach $file (@files)
  172.     {
  173.     do_file ($file, $file, $entry);
  174.     }
  175. }
  176.