@@ -381,7 +381,7 @@ sub dosubst_private {
381
381
@pairs ,
382
382
((ref $src ) ? %{$src -> [1]} : ()),
383
383
PRIV => sub {return " $sname ->$_ [0]" },
384
- COMP => sub {return " $pname ->$_ [0]" },
384
+ COMP => sub {my $r = " $pname ->$_ [0]" ; $sig -> other_is_out( $_ [0])? " (*( $r )) " : $r },
385
385
CROAK => sub {PDL::PP::pp_line_numbers(__LINE__ -1, " return PDL->make_error(PDL_EUSERERROR, \" Error in $name :\" @{[join ',', @_ ]})" )},
386
386
NAME => sub {return $name },
387
387
MODULE => sub {return $: :PDLMOD},
@@ -1573,6 +1573,7 @@ EOD
1573
1573
my %ptypes = map +($_ => $$optypes {$_ } ? $$optypes {$_ }-> get_decl(' ' , {VarArrays2Ptrs => 1}) : ' pdl *' ), @args ;
1574
1574
my %out = map +($_ => 1), $sig -> names_out_nca;
1575
1575
my %outca = map +($_ => 1), $sig -> names_oca;
1576
+ my %other_out = map +($_ => 1), $sig -> other_out;
1576
1577
my %tmp = map +($_ => 1), $sig -> names_tmp;
1577
1578
# remember, otherpars *are* input vars
1578
1579
my $nout = grep $_ , values %out ;
@@ -1590,25 +1591,28 @@ EOD
1590
1591
# These are used in creating output variables. One variable (ex: SV * outvar1_SV;)
1591
1592
# is needed for each output and output create always argument
1592
1593
my $svdecls = join " \n " , map indent(" SV *${_}_SV = NULL;" ,$ci ), $sig -> names_out;
1593
- my ($xsargs , $xsdecls ) = (' ' , ' ' ); my %already_read ;
1594
+ my ($xsargs , $xsdecls ) = (' ' , ' ' ); my %already_read ; my $cnt = 0; my %outother2cnt ;
1594
1595
foreach my $x (@args ) {
1595
1596
next if $outca {$x };
1596
1597
last if $out {$x } || ($other {$x } && exists $defaults -> {$x });
1597
1598
$already_read {$x } = 1;
1598
1599
$xsargs .= " $x , " ; $xsdecls .= " \n\t $ptypes {$x }$x " ;
1600
+ $outother2cnt {$x } = $cnt if $other {$x } && $other_out {$x };
1601
+ $cnt ++;
1599
1602
}
1600
- my $pars = join " \n " ,map indent(" $_ ;" ,$ci ), $sig -> alldecls(0, \%already_read );
1603
+ my $pars = join " \n " ,map indent(" $_ ;" ,$ci ), $sig -> alldecls(0, 0, \%already_read );
1604
+ $svdecls = join " \n " , grep length , $svdecls , map indent(qq{ SV *${_}_SV = @{[defined($outother2cnt {$_ })?"ST($outother2cnt {$_ })":'NULL']};} ,$ci ), $sig -> other_out;
1601
1605
my @create = (); # The names of variables which need to be created by calling
1602
1606
# the 'initialize' perl routine from the correct package.
1603
1607
$ci = ' ' ; # Current indenting
1604
1608
# clause for reading in all variables
1605
- my $clause1 = $inplacecheck ; my $cnt = 0;
1609
+ my $clause1 = $inplacecheck ; $cnt = 0;
1606
1610
foreach my $x (@args ) {
1607
1611
if ($outca {$x }) {
1608
1612
push @create , $x ;
1609
1613
} else {
1610
1614
my ($setter , $type ) = typemap($ptypes {$x }, ' get_inputmap' );
1611
- $setter = typemap_eval($setter , {var => $x , type => $type , arg => ($out {$x } ? " ${x} _SV = " : ' ' )." ST($cnt )" });
1615
+ $setter = typemap_eval($setter , {var => $x , type => $type , arg => ($out {$x }|| $other_out { $x } ? " ${x} _SV = " : ' ' )." ST($cnt )" });
1612
1616
$setter =~ s / .*?(?=$x\s *=\s *)// s ; # zap any declarations like whichdims_count
1613
1617
$clause1 .= indent(" $setter ;\n " ,$ci ) if !$already_read {$x };
1614
1618
$cnt ++;
@@ -1626,7 +1630,7 @@ EOD
1626
1630
push @create , $x ;
1627
1631
} else {
1628
1632
my ($setter , $type ) = typemap($ptypes {$x }, ' get_inputmap' );
1629
- $setter = typemap_eval($setter , {var => $x , type => $type , arg => " ST($cnt )" });
1633
+ $setter = typemap_eval($setter , {var => $x , type => $type , arg => ( $other_out { $x } ? " ${x} _SV = " : ' ' ). " ST($cnt )" });
1630
1634
$setter =~ s / ^(.*?)=\s *// s , $setter = " $x = ($defaults_rawcond ) ? ($defaults ->{$x }) : ($setter )" if exists $defaults -> {$x };
1631
1635
$clause3 .= indent(" $setter ;\n " ,$ci ) if !$already_read {$x };
1632
1636
$cnt ++;
@@ -1672,14 +1676,26 @@ END
1672
1676
my @outs = $sig -> names_out; # names of output ndarrays in calling order
1673
1677
my $clause1 = join ' ;' , map " ST($_ ) = $outs [$_ ]_SV" , 0 .. $#outs ;
1674
1678
$clause1 = PDL::PP::pp_line_numbers(__LINE__ -1, " PDL_XS_RETURN($clause1 )" );
1679
+ my @other_out = $sig -> other_out;
1680
+ my $optypes = $sig -> otherobjs;
1681
+ my %ptypes = map +($_ => $$optypes {$_ }-> get_decl(' ' , {VarArrays2Ptrs => 1})), @other_out ;
1682
+ for my $x (@other_out ) {
1683
+ my ($setter , $type ) = typemap($ptypes {$x }, ' get_outputmap' );
1684
+ $setter = typemap_eval($setter , {var => $x , type => $type , arg => " tsv" });
1685
+ $clause1 = <<EOF . $clause1 ;
1686
+ { SV *tsv = NULL;
1687
+ $setter
1688
+ sv_setsv(${x} _SV, tsv); sv_2mortal(tsv); }
1689
+ EOF
1690
+ }
1675
1691
$clause1 ;
1676
1692
}),
1677
1693
1678
1694
PDL::PP::Rule-> new(" NewXSHdr" , [" NewXSName" ," SignatureObj" ],
1679
1695
sub {
1680
1696
my ($name ,$sig ) = @_ ;
1681
1697
my $shortpars = join ' ,' , @{ $sig -> allnames(1) };
1682
- my $longpars = join " \n " , map " \t $_ " , $sig -> alldecls(1);
1698
+ my $longpars = join " \n " , map " \t $_ " , $sig -> alldecls(1, 0 );
1683
1699
return <<END ;
1684
1700
\n void
1685
1701
$name ($shortpars )
@@ -1690,16 +1706,16 @@ END
1690
1706
PDL::PP::Rule-> new(" NewXSCHdrs" , [" RunFuncName" ," SignatureObj" ," GlobalNew" ],
1691
1707
sub {
1692
1708
my ($name ,$sig ,$gname ) = @_ ;
1693
- my $longpars = join " ," , $sig -> alldecls(0);
1709
+ my $longpars = join " ," , $sig -> alldecls(0, 1 );
1694
1710
my $opening = ' pdl_error PDL_err = {0, NULL, 0};' ;
1695
1711
my $closing = ' return PDL_err;' ;
1696
1712
return [" pdl_error $name ($longpars ) {$opening " ," $closing }" ,
1697
1713
" PDL->$gname = $name ;" ];
1698
1714
}),
1699
1715
PDL::PP::Rule-> new([" RunFuncCall" ," RunFuncHdr" ],[" RunFuncName" ," SignatureObj" ], sub {
1700
1716
my ($func_name ,$sig ) = @_ ;
1701
- my $shortpars = join ' ,' , @{ $sig -> allnames(0) };
1702
- my $longpars = join " ," , $sig -> alldecls(0);
1717
+ my $shortpars = join ' ,' , map $sig -> other_is_out( $_ )? " & $_ " : $_ , @{ $sig -> allnames(0) };
1718
+ my $longpars = join " ," , $sig -> alldecls(0, 1 );
1703
1719
(PDL::PP::pp_line_numbers(__LINE__ -1, " PDL->barf_if_error($func_name ($shortpars ));" ),
1704
1720
" pdl_error $func_name ($longpars )" );
1705
1721
}),
@@ -1954,6 +1970,7 @@ EOF
1954
1970
push @op_flags , ' PDL_TRANS_BADPROCESS' if $badflag ;
1955
1971
push @op_flags , ' PDL_TRANS_BADIGNORE' if defined $badflag and !$badflag ;
1956
1972
push @op_flags , ' PDL_TRANS_NO_PARALLEL' if $noPthreadFlag ;
1973
+ push @op_flags , ' PDL_TRANS_OUTPUT_OTHERPAR' if $sig -> other_any_out;
1957
1974
my $op_flags = join (' |' , @op_flags ) || ' 0' ;
1958
1975
my $iflags = join (' |' , grep $_ , $affflag , $revflag , $flowflag ) || ' 0' ;
1959
1976
my $gentypes_txt = join (" , " , (map PDL::Type-> new($_ )-> sym, @$gentypes ), ' -1' );
0 commit comments