$var_init =~ s/"/\\"/g;
s/\s+/ /g;
- my ($var_type, $var_addr, $var_name) = /^(.*?[^& ]) *(\&?) *\b(\w+)$/s
+ my ($var_type, $var_addr, $var_name) = /^(.*?[^&\s])\s*(\&?)\s*\b(\w+)$/s
or blurt("Error: invalid argument declaration '$line'"), next;
# Check for duplicate definitions
$proto_arg[$var_num] = ProtoString($var_type)
if $var_num ;
- if ($var_addr) {
- $var_addr{$var_name} = 1;
- $func_args =~ s/\b($var_name)\b/&$1/;
- }
+ $func_args =~ s/\b($var_name)\b/&$1/ if $var_addr;
if ($var_init =~ /^[=;]\s*NO_INIT\s*;?\s*$/
- or $in_out{$var_name} and $in_out{$var_name} eq 'OUTLIST'
+ or $in_out{$var_name} and $in_out{$var_name} =~ /^OUT/
and $var_init !~ /\S/) {
if ($name_printed) {
print ";\n";
} else {
&generate_output($var_types{$outarg}, $var_num, $outarg, $DoSetMagic);
}
+ delete $in_out{$outarg} # No need to auto-OUTPUT
+ if exists $in_out{$outarg} and $in_out{$outarg} =~ /OUT$/;
}
}
# initialize info arrays
undef(%args_match);
undef(%var_types);
- undef(%var_addr);
undef(%defaults);
undef($class);
undef($static);
undef(@arg_with_types) ;
undef($processing_arg_with_types) ;
undef(%arg_types) ;
- undef(@in_out) ;
+ undef(@outlist) ;
undef(%in_out) ;
undef($proto_in_this_xsub) ;
undef($scope_in_this_xsub) ;
$orig_args =~ s/\\\s*/ /g; # process line continuations
- my %out_vars;
+ my %only_output;
if ($process_argtypes and $orig_args =~ /\S/) {
my $args = "$orig_args ,";
if ($args =~ /^( (??{ $C_arg }) , )* $ /x) {
next unless length $pre;
my $out_type;
my $inout_var;
- if ($process_inout and s/^(IN|IN_OUTLIST|OUTLIST)\s+//) {
+ if ($process_inout and s/^(IN|IN_OUTLIST|OUTLIST|OUT|IN_OUT)\s+//) {
my $type = $1;
$out_type = $type if $type ne 'IN';
- $arg =~ s/^(IN|IN_OUTLIST|OUTLIST)\s+//;
+ $arg =~ s/^(IN|IN_OUTLIST|OUTLIST|OUT|IN_OUT)\s+//;
}
if (/\W/) { # Has a type
push @arg_with_types, $arg;
$arg_types{$name} = $arg;
$_ = "$name$default";
}
- $out_vars{$_} = 1 if $out_type eq 'OUTLIST';
- push @in_out, $name if $out_type;
+ $only_output{$_} = 1 if $out_type =~ /^OUT/;
+ push @outlist, $name if $out_type =~ /OUTLIST$/;
$in_out{$name} = $out_type if $out_type;
}
} else {
} else {
@args = split(/\s*,\s*/, $orig_args);
for (@args) {
- if ($process_inout and s/^(IN|IN_OUTLIST|OUTLIST)\s+//) {
+ if ($process_inout and s/^(IN|IN_OUTLIST|OUTLIST|IN_OUT|OUT)\s+//) {
my $out_type = $1;
next if $out_type eq 'IN';
- $out_vars{$_} = 1 if $out_type eq 'OUTLIST';
- push @in_out, $name;
+ $only_output{$_} = 1 if $out_type =~ /^OUT/;
+ push @outlist, $name if $out_type =~ /OUTLIST$/;
$in_out{$_} = $out_type;
}
}
last;
}
}
- if ($out_vars{$args[$i]}) {
+ if ($only_output{$args[$i]}) {
push @args_num, undef;
} else {
push @args_num, ++$num_args;
undef %outargs ;
process_keyword("POSTCALL|OUTPUT|ALIAS|ATTRS|PROTOTYPE");
+ &generate_output($var_types{$_}, $args_match{$_}, $_, $DoSetMagic)
+ for grep $in_out{$_} =~ /OUT$/, keys %in_out;
+
# all OUTPUT done, so now push the return value on the stack
if ($gotRETVAL && $RETVAL_code) {
print "\t$RETVAL_code\n";
$xsreturn = 1 if $ret_type ne "void";
my $num = $xsreturn;
- my $c = @in_out;
+ my $c = @outlist;
print "\tXSprePUSH;" if $c and not $prepush_done;
print "\tEXTEND(SP,$c);\n" if $c;
$xsreturn += $c;
- generate_output($var_types{$_}, $num++, $_, 0, 1) for @in_out;
+ generate_output($var_types{$_}, $num++, $_, 0, 1) for @outlist;
# do cleanup
process_keyword("CLEANUP|ALIAS|ATTRS|PROTOTYPE") ;