Algorithm-ConsistentHash-Ketama
view release on metacpan or search on metacpan
inc/Module/Install/XSUtil.pm view on Meta::CPAN
else{
$h_files = +{ map{ $_ => undef } @_ };
}
$self->_xs_initialize();
my @not_found;
my $h_map = $self->{xsu_header_map} || {};
while(my($ident, $path) = each %{$h_files}){
$path ||= $h_map->{$ident} || File::Spec->join('.', $ident);
$path = File::Spec->canonpath($path);
unless($path && -e $path){
push @not_found, $ident;
next;
}
$ToInstall{$path} = File::Spec->join('$(INST_ARCHAUTODIR)', $ident);
_verbose "install: $path as $ident" if _VERBOSE;
my @funcs = $self->_extract_functions_from_header_file($path);
if(@funcs){
$self->cc_append_to_funclist(@funcs);
}
}
if(@not_found){
die "Header file(s) not found: @not_found\n";
}
return;
}
my $home_directory;
sub _extract_functions_from_header_file{
my($self, $h_file) = @_;
my @functions;
($home_directory) = <~> unless defined $home_directory;
# get header file contents through cpp(1)
my $contents = do {
my $mm = $self->makemaker_args;
my $cppflags = q{"-I}. File::Spec->join($Config{archlib}, 'CORE') . q{"};
$cppflags =~ s/~/$home_directory/g;
$cppflags .= ' ' . $mm->{INC} if $mm->{INC};
$cppflags .= ' ' . ($mm->{CCFLAGS} || $Config{ccflags});
$cppflags .= ' ' . $mm->{DEFINE} if $mm->{DEFINE};
my $add_include = _is_msvc() ? '-FI' : '-include';
$cppflags .= ' ' . join ' ',
map{ qq{$add_include "$_"} } qw(EXTERN.h perl.h XSUB.h);
my $cppcmd = qq{$Config{cpprun} $cppflags $h_file};
# remove all the -arch options to workaround gcc errors:
# "-E, -S, -save-temps and -M options are not allowed
# with multiple -arch flags"
$cppcmd =~ s/ -arch \s* \S+ //xmsg;
_verbose("extract functions from: $cppcmd") if _VERBOSE;
`$cppcmd`;
};
unless(defined $contents){
die "Cannot call C pre-processor ($Config{cpprun}): $! ($?)";
}
# remove other include file contents
my $chfile = q/\# (?:line)? \s+ \d+ /;
$contents =~ s{
^$chfile \s+ (?!"\Q$h_file\E")
.*?
^(?= $chfile)
}{}xmsig;
if(_VERBOSE){
local *H;
open H, "> $h_file.out"
and print H $contents
and close H;
}
while($contents =~ m{
([^\\;\s]+ # type
\s+
([a-zA-Z_][a-zA-Z0-9_]*) # function name
\s*
\( [^;#]* \) # argument list
[\w\s\(\)]* # attributes or something
;) # end of declaration
}xmsg){
my $decl = $1;
my $name = $2;
next if $decl =~ /\b typedef \b/xms;
next if $name =~ /^_/xms; # skip something private
push @functions, $name;
if(_VERBOSE){
$decl =~ tr/\n\r\t / /s;
$decl =~ s/ (\Q$name\E) /<$name>/xms;
_verbose("decl: $decl");
}
}
return @functions;
}
sub cc_append_to_funclist{
my($self, @functions) = @_;
$self->_xs_initialize();
my $mm = $self->makemaker_args;
( run in 0.375 second using v1.01-cache-2.11-cpan-4991d5b9bd9 )