home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / FunctionMap.pm < prev    next >
Encoding:
Perl POD Document  |  2004-03-04  |  5.1 KB  |  209 lines

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