dougm       01/03/04 19:46:32

  Added:       lib/ModPerl MapUtil.pm
  Log:
  utilties/base class for ModPerl::{Function,Structure,Type}Map
  
  Revision  Changes    Path
  1.1                  modperl-2.0/lib/ModPerl/MapUtil.pm
  
  Index: MapUtil.pm
  ===================================================================
  package ModPerl::MapUtil;
  
  use strict;
  use warnings;
  use Exporter ();
  use Apache::Build ();
  
  our @EXPORT_OK = qw(list_first disabled_reason
                      function_table structure_table
                      xs_glue_dirs);
  
  our @ISA = qw(Exporter);
  
  my %disabled_map = (
      '!' => 'disabled or not yet implemented',
      '~' => 'implemented but not auto-generated',
      '-' => 'likely never be available to Perl',
      '>' => '"private" to apache',
      '?' => 'unclassified',
  );
  
  my $function_table = [];
  
  sub function_table {
      return $function_table if @$function_table;
      @$function_table = (@$Apache::FunctionTable, @$ModPerl::FunctionTable);
      $function_table;
  }
  
  my $structure_table = [];
  
  sub structure_table {
      return $structure_table if @$structure_table;
      @$structure_table = (@$Apache::StructureTable);
      $structure_table;
  }
  
  sub disabled_reason {
      $disabled_map{+shift} || 'unknown';
  }
  
  sub xs_glue_dirs {
      Apache::Build->build_config->mp_xs_glue_dir;
  }
  
  sub list_first (&@) {
      my $code = shift;
  
      for (@_) {
          return $_ if $code->();
      }
  
      undef;
  }
  
  package ModPerl::MapBase;
  
  *function_table = \&ModPerl::MapUtil::function_table;
  *structure_table = \&ModPerl::MapUtil::structure_table;
  
  sub readline {
      my $fh = shift;
  
      while (<$fh>) {
          chomp;
          s/^\s+//; s/\s+$//;
          s/^\#.*//;
          s/\s*\#.*//;
  
          next unless $_;
  
          if (s:\\$::) {
              my $cur = $_;
              $_ = $cur . $fh->readline;
              return $_;
          }
  
          return $_;
      }
  }
  
  our $MapDir;
  
  my $map_classes = join '|', qw(type structure function);
  
  sub map_files {
      my $self = shift;
      my $package = ref($self) || $self;
  
      my($wanted) = $package =~ /($map_classes)/io;
  
      my(@dirs) = (($MapDir || './xs'), ModPerl::MapUtil::xs_glue_dirs());
  
      my @files;
  
      for my $dir (map { -d "$_/maps" ? "$_/maps" : $_ } @dirs) {
          opendir my $dh, $dir or warn "opendir $dir: $!";
  
          for (readdir $dh) {
              next unless /\.map$/;
  
              my $file = "$dir/$_";
  
              if ($wanted) {
                  next unless $file =~ /$wanted/i;
              }
  
              #print "$package => $file\n";
              push @files, $file;
          }
  
          closedir $dh;
      }
  
      return @files;
  }
  
  sub parse_keywords {
      my($self, $line) = @_;
      my %words;
  
      for my $pair (split /\s+/, $line) {
          my($key, $val) = split /=/, $pair;
  
          unless ($key and $val) {
              die "parse error ($ModPerl::MapUtil::MapFile line $.)";
          }
  
          $words{$key} = $val;
      }
  
      %words;
  }
  
  sub parse_map_files {
      my($self) = @_;
  
      my $map = {};
  
      for my $file (map_files($self)) {
          open my $fh, $file or die "open $file: $!";
          local $ModPerl::MapUtil::MapFile = $file;
          bless $fh, __PACKAGE__;
          $self->parse($fh, $map);
          close $fh;
      }
  
      return $map;
  }
  
  1;
  __END__
  
  
  

Reply via email to