Skip to content

Commit cfedea9

Browse files
committed
ParseXS: refactor: turn param parsing into a sub
Currently the parsing of an XSUB's signature, and the parsing of the individual comma-separated items within that signature, are done in the same function, Params->parse(). This commit is the first of three which will extract out the latter into a separate Param->parse() method. For now, the per-param code is kept in-place (to make the diff easier to understand), but is wrapped within an immediately-called anon sub, in preparation to be moved. So before, the code was (very simplified): for (split /,/, $params_text) { ... parse type, name, init etc ... next if can't parse; my $param = Param->new(var = $var, type => $type, ...); push @{$params->{kids}}, $param; } After this commit, it looks more like: for (split /,/, $params_text) { my $param = Param->new(); sub { my $param = shift; ... ... parse type, name, init etc ... return if can't parse; $param->{var} = $var; ... return 1; }->{$param, ...) or next; push @{$params->{kids}}, $param; } Note that the inner sub leaves pushing the new param, updating the names hash and setting the arg_num to the caller. In theory there are no functional changes, except that when a synthetic RETVAL is being kept (but its position within kids moved), we now keep the Param hash and update its contents, rather than replace it with a new hash. This shouldn't make any difference.
1 parent df71d29 commit cfedea9

File tree

1 file changed

+40
-33
lines changed
  • dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS

1 file changed

+40
-33
lines changed

dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,7 +1989,7 @@ sub parse {
19891989
$self->{names}{RETVAL} = $param;
19901990
}
19911991

1992-
for (@param_texts) {
1992+
for my $param_text (@param_texts) {
19931993
# Process each parameter. A parameter is of the general form:
19941994
#
19951995
# OUT char* foo = expression
@@ -2007,19 +2007,29 @@ sub parse {
20072007
# = default default value - only allowed under
20082008
# $pxs->{config_allow_argtypes}
20092009

2010-
s/^\s+//;
2011-
s/\s+$//;
2010+
$param_text =~ s/^\s+//;
2011+
$param_text =~ s/\s+$//;
20122012

20132013
# Process ellipsis (...)
20142014

20152015
$pxs->blurt("further XSUB parameter seen after ellipsis (...)")
20162016
if $self->{seen_ellipsis};
20172017

2018-
if ($_ eq '...') {
2018+
if ($param_text eq '...') {
20192019
$self->{seen_ellipsis} = 1;
20202020
next;
20212021
}
20222022

2023+
my $param = ExtUtils::ParseXS::Node::Param->new();
2024+
2025+
sub {
2026+
my ExtUtils::ParseXS::Node::Param $param = shift;
2027+
my ExtUtils::ParseXS $pxs = shift;
2028+
my $params = shift; # parent Params
2029+
my $param_text = shift;
2030+
2031+
$_ = $param_text;
2032+
20232033
# Decompose parameter into its components.
20242034
# Note that $name can be either 'foo' or 'length(foo)'
20252035

@@ -2046,55 +2056,47 @@ sub parse {
20462056
if (/^ SV \s* \* $/x) {
20472057
# special-case SV* as a placeholder for backwards
20482058
# compatibility.
2049-
push @{$self->{kids}},
2050-
ExtUtils::ParseXS::Node::Param->new( {
2051-
var => 'SV *',
2052-
arg_num => ++$nargs,
2053-
});
2054-
}
2055-
else {
2056-
$pxs->blurt("Unparseable XSUB parameter: '$_'");
2059+
$param->{var} = 'SV *';
2060+
return 1;
20572061
}
2058-
next;
2062+
$pxs->blurt("Unparseable XSUB parameter: '$_'");
2063+
return;
20592064
}
20602065

20612066
undef $type unless length($type) && $type =~ /\S/;
2062-
2063-
my ExtUtils::ParseXS::Node::Param $param
2064-
= ExtUtils::ParseXS::Node::Param->new( {
2065-
var => $name,
2066-
});
2067+
$param->{var} = $name;
20672068

20682069
# Check for duplicates
20692070

2070-
my $old_param = $self->{names}{$name};
2071+
my $old_param = $params->{names}{$name};
20712072
if ($old_param) {
2073+
# Normally a dup parameter is an error, but we allow RETVAL as
2074+
# a real parameter, which overrides the synthetic one which
2075+
# was added earlier if the return value isn't void.
20722076
if ( $name eq 'RETVAL'
20732077
and $old_param->{is_synthetic}
20742078
and !defined $old_param->{arg_num})
20752079
{
20762080
# RETVAL is currently fully synthetic. Now that it has
20772081
# been declared as a parameter too, override any implicit
20782082
# RETVAL declaration. Delete the original param from the
2079-
# param list.
2080-
@{$self->{kids}} = grep $_ != $old_param, @{$self->{kids}};
2083+
# param list and later re-add it as a parameter in it's
2084+
# correct position.
2085+
@{$params->{kids}} = grep $_ != $old_param, @{$params->{kids}};
20812086
# If the param declaration includes a type, it becomes a
20822087
# real parameter. Otherwise the param is kept as
20832088
# 'semi-real' (synthetic, but with an arg_num) until such
20842089
# time as it gets a type set in INPUT, which would remove
20852090
# the synthetic/no_init.
2086-
$param = $old_param if !defined $type;
2091+
%$param = %$old_param unless defined $type;
20872092
}
20882093
else {
20892094
$pxs->blurt(
20902095
"Error: duplicate definition of parameter '$name' ignored");
2091-
next;
2096+
return;
20922097
}
20932098
}
20942099

2095-
push @{$self->{kids}}, $param;
2096-
$self->{names}{$name} = $param;
2097-
20982100
# Process optional IN/OUT etc modifier
20992101

21002102
if (defined $out_type) {
@@ -2155,7 +2157,6 @@ sub parse {
21552157
# to be used in "usage: ..." error messages.
21562158
my $report_def = '';
21572159
if (defined $default) {
2158-
$opt_args++;
21592160
# The default expression for reporting usage. For backcompat,
21602161
# sometimes preserve the spaces either side of the '='
21612162
$report_def = ((defined $type or $is_length) ? '' : $sp1)
@@ -2164,12 +2165,18 @@ sub parse {
21642165
$param->{default} = $default;
21652166
}
21662167

2167-
if ($out_type eq "OUTLIST" or $is_length) {
2168-
$param->{arg_num} = undef;
2169-
}
2170-
else {
2171-
$param->{arg_num} = ++$nargs;
2172-
}
2168+
1;
2169+
}->($param, $pxs, $self, $param_text)
2170+
or next;
2171+
2172+
push @{$self->{kids}}, $param;
2173+
$self->{names}{$param->{var}} = $param unless $param->{var} eq 'SV *';
2174+
$opt_args++ if defined $param->{default};
2175+
# Give the param a number if it will consume one of the passed args
2176+
$param->{arg_num} = ++$nargs
2177+
unless ( defined $param->{in_out} && $param->{in_out} eq "OUTLIST"
2178+
or $param->{is_length})
2179+
21732180
} # for (@param_texts)
21742181

21752182
$self->{nargs} = $nargs;

0 commit comments

Comments
 (0)