home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / FunctionMap.pm < prev    next >
Encoding:
Perl POD Document  |  2002-05-26  |  4.7 KB  |  195 lines

  1. package ModPerl::FunctionMap;
  2.  
  3. use strict;
  4. use warnings FATAL => 'all';
  5. use ModPerl::MapUtil qw();
  6. use ModPerl::ParseSource ();
  7.  
  8. our @ISA = qw(ModPerl::MapBase);
  9.  
  10. sub new {
  11.     my $class = shift;
  12.     bless {}, $class;
  13. }
  14.  
  15. #for adding to function.map
  16. sub generate {
  17.     my $self = shift;
  18.  
  19.     my $missing = $self->check;
  20.     return unless $missing;
  21.  
  22.     print " $_\n" for @$missing;
  23. }
  24.  
  25. sub disabled { shift->{disabled} }
  26.  
  27. #look for functions that do not exist in *.map
  28. sub check {
  29.     my $self = shift;
  30.     my $map = $self->get;
  31.  
  32.     my @missing;
  33.     my $mp_func = ModPerl::ParseSource->wanted_functions;
  34.  
  35.     for my $name (map $_->{name}, @{ $self->function_table() }) {
  36.         next if exists $map->{$name};
  37.         push @missing, $name unless $name =~ /^($mp_func)/o;
  38.     }
  39.  
  40.     return @missing ? \@missing : undef;
  41. }
  42.  
  43. #look for functions in *.map that do not exist
  44. my $special_name = qr{(^DEFINE_|DESTROY$)};
  45.  
  46. sub check_exists {
  47.     my $self = shift;
  48.  
  49.     my %functions = map { $_->{name}, 1 } @{ $self->function_table() };
  50.     my @missing = ();
  51.  
  52.     for my $name (keys %{ $self->{map} }) {
  53.         next if $functions{$name};
  54.         push @missing, $name unless $name =~ $special_name;
  55.     }
  56.  
  57.     return @missing ? \@missing : undef;
  58. }
  59.  
  60. my $keywords = join '|', qw(MODULE PACKAGE PREFIX BOOT);
  61.  
  62. sub guess_prefix {
  63.     my $entry = shift;
  64.  
  65.     my($name, $class) = ($entry->{name}, $entry->{class});
  66.     my $prefix = "";
  67.     $name =~ s/^DEFINE_//;
  68.     $name =~ s/^mpxs_//i;
  69.  
  70.     (my $modprefix = ($entry->{class} || $entry->{module}) . '_') =~ s/::/__/g;
  71.     (my $guess = lc $modprefix) =~ s/_+/_/g;
  72.  
  73.     $guess =~ s/(apache)_/($1|ap)_{1,2}/;
  74.  
  75.     if ($name =~ s/^($guess|$modprefix).*/$1/i) {
  76.         $prefix = $1;
  77.     }
  78.     else {
  79.         if ($name =~ /^(apr?_)/) {
  80.             $prefix = $1;
  81.         }
  82.     }
  83.  
  84.     #print "GUESS prefix=$guess, name=$entry->{name} -> $prefix\n";
  85.  
  86.     return $prefix;
  87. }
  88.  
  89. sub parse {
  90.     my($self, $fh, $map) = @_;
  91.     my %cur;
  92.     my $disabled = 0;
  93.  
  94.     while ($fh->readline) {
  95.         if (/($keywords)=/o) {
  96.             $disabled = s/^\W//; #module is disabled
  97.             my %words = $self->parse_keywords($_);
  98.  
  99.             if ($words{MODULE}) {
  100.                 %cur = ();
  101.             }
  102.  
  103.             if ($words{PACKAGE}) {
  104.                 delete $cur{CLASS};
  105.             }
  106.  
  107.             for (keys %words) {
  108.                 $cur{$_} = $words{$_};
  109.             }
  110.  
  111.             next;
  112.         }
  113.  
  114.         my($name, $dispatch, $argspec, $alias) = split /\s*\|\s*/;
  115.         my $return_type;
  116.  
  117.         if ($name =~ s/^([^:]+)://) {
  118.             $return_type = $1;
  119.             $return_type =~ s/\s+$//;  # allow: char *    :....
  120.         }
  121.  
  122.         if ($name =~ s/^(\W)// or not $cur{MODULE} or $disabled) {
  123.             #notimplemented or cooked by hand
  124.             $map->{$name} = undef;
  125.             push @{ $self->{disabled}->{ $1 || '!' } }, $name;
  126.             next;
  127.         }
  128.  
  129.         if (my $package = $cur{PACKAGE}) {
  130.             unless ($package eq 'guess') {
  131.                 $cur{CLASS} = $package;
  132.             }
  133.             if ($cur{ISA}) {
  134.                 $self->{isa}->{ $cur{MODULE} }->{$package} = delete $cur{ISA};
  135.             }
  136.             if ($cur{BOOT}) {
  137.                 $self->{boot}->{ $cur{MODULE} } = delete $cur{BOOT};
  138.             }
  139.         }
  140.         else {
  141.             $cur{CLASS} = $cur{MODULE};
  142.         }
  143.  
  144.         #XXX: make_prefix() stuff should be here, not ModPerl::WrapXS
  145.         if ($name =~ /^DEFINE_/ and $cur{CLASS}) {
  146.             $name =~ s{^(DEFINE_)(.*)}
  147.               {$1 . ModPerl::WrapXS::make_prefix($2, $cur{CLASS})}e;
  148.         }
  149.  
  150.         my $entry = $map->{$name} = {
  151.            name        => $alias || $name,
  152.            dispatch    => $dispatch,
  153.            argspec     => $argspec ? [split /\s*,\s*/, $argspec] : "",
  154.            return_type => $return_type,
  155.            alias       => $alias,
  156.         };
  157.  
  158.         for (keys %cur) {
  159.             $entry->{lc $_} = $cur{$_};
  160.         }
  161.  
  162.         #avoid 'use of uninitialized value' warnings
  163.         $entry->{$_} ||= "" for keys %{ $entry };
  164.         if ($entry->{dispatch} =~ /_$/) {
  165.             $entry->{dispatch} .= $name;
  166.         }
  167.     }
  168. }
  169.  
  170. sub get {
  171.     my $self = shift;
  172.  
  173.     $self->{map} ||= $self->parse_map_files;
  174. }
  175.  
  176. sub prefixes {
  177.     my $self = shift;
  178.     $self = ModPerl::FunctionMap->new unless ref $self;
  179.  
  180.     my $map = $self->get;
  181.     my %prefix;
  182.  
  183.     while (my($name, $ent) = each %$map) {
  184.         next unless $ent->{prefix};
  185.         $prefix{ $ent->{prefix} }++;
  186.     }
  187.  
  188.     $prefix{$_} = 1 for qw(ap_ apr_); #make sure we get these
  189.  
  190.     [keys %prefix]
  191. }
  192.  
  193. 1;
  194. __END__
  195.