Devel-PPPort
view release on metacpan or search on metacpan
parts/apicheck.pl view on Meta::CPAN
my $long_form_required = $f->{'flags'}{'o'} || $f->{'flags'}{'f'};
my $stack = '';
my @arg;
my $aTHX = '';
my $i = 1; # Argument number
my $ca;
my $varargs = 0;
# Loop through the function's args, building up the declarations
for $ca (@{$f->{'args'}}) {
my $a = $ca->[0]; # 1th is the name, 0th is its type
if ($a eq '...') {
$varargs = 1;
push @arg, qw(VARarg1 VARarg2 VARarg3);
last;
}
# Split this argument into its components. The formal parameter name is
# discarded; we're just interested in the type and its modifiers
my($t, $p, $d) = $a =~ /^ ( (?: " [^"]* " ) # literal string type => $t
| (?: \w+ (?: \s+ \w+ )* ) # name of type => $t
)
\s*
( \** ) # optional pointer(s) => $p
(?: \s* \b const \b \s* )? # opt. const
( (?: \[ [^\]]* \] )* ) # opt. dimension(s)=> $d
$/x
or die "$0 - cannot parse argument: [$a] in $short_form\n";
# Replace a special argument type by something that will compile.
if (exists $amap{$t}) {
if ($p or $d) {
die "$short_form had type '$t', which should have been the"
. " whole type. Instead '$p' or '$d' was non-empty";
}
push @arg, $amap{$t};
next;
}
# Certain types, like 'void', get remapped.
$t = $tmap{$t} || $t;
if ($t =~ / ^ " [^"]* " $/x) { # Use the literal string, literally
push @arg, $t;
}
else {
my $v = 'arg' . $i++; # Argument number
push @arg, $v;
my $no_const_n = $t; # Get rid of any remaining 'const's
$no_const_n =~ s/\bconst\b//g unless $p;
# Declare this argument
$stack .= " static $no_const_n $p$v$d;\n";
}
}
# Declare thread context for functions and macros that might need it.
# (Macros often fail to say they don't need it.)
unless ($Tflag) {
$stack = " dTHX;\n$stack"; # Harmless to declare even if not needed
$aTHX = @arg ? 'aTHX_ ' : 'aTHX';
}
# If this function is on the list of things that need extra declarations,
# add them.
if ($stack{$short_form}) {
my $s = '';
for (@{$stack{$short_form}}) {
$s .= " $_\n";
}
$stack = "$s$stack";
}
my $args = join ', ', @arg;
my $prefix = "";
my $rvt = $f->{'ret'}; # Type of return value
# Replace generic 'type'
$rvt = 'int' if defined $rvt && $rvt eq 'type';
# Failure to specify a return type in the apidoc line means void
$rvt = 'void' unless $rvt;
# Remove const, as otherwise could declare something that is impossible to
# set.
$rvt =~ s/\bconst\b//g;
my $ret;
if ($void{$rvt}) { # Certain return types are instead considered void
$ret = $castvoid{$short_form} ? '(void) ' : '';
}
else {
$stack .= " $rvt rval;\n";
$ret = $ignorerv{$short_form} ? '(void) ' : "rval = ";
}
my $THX_prefix = "";
my $THX_suffix = "";
# Add parens to functions that take an argument list, even if empty
unless ($nflag) {
$THX_suffix = "($aTHX$args)";
$args = "($args)";
}
# Single trailing underscore in name means is a comma operator
if ($short_form =~ /[^_]_$/) {
$THX_suffix .= ' 1';
$args .= ' 1';
}
# Single leading underscore in a few names means is a comma operator
if ($short_form =~ /^ _[ adp] (?: THX | MY_CXT ) /x) {
$THX_prefix = '1 ';
$prefix = '1 ';
}
( run in 2.422 seconds using v1.01-cache-2.11-cpan-800906f7e73 )