diff --git a/Basic/Core/Core.pm b/Basic/Core/Core.pm index 1d01f9a05..a56000411 100644 --- a/Basic/Core/Core.pm +++ b/Basic/Core/Core.pm @@ -463,6 +463,7 @@ a single Empty PDL, you get back the Empty PDL (no padding). =for ref Returns a 'null' ndarray. +It is an error to pass one of these as an input to a function. =for usage diff --git a/Basic/Core/pdlthread.c b/Basic/Core/pdlthread.c index 16a2b47ee..85b126460 100644 --- a/Basic/Core/pdlthread.c +++ b/Basic/Core/pdlthread.c @@ -247,6 +247,11 @@ pdl_error pdl_dim_checks( )); } else { PDL_Indx *dims = pdl->dims; + if (pdl->state & PDL_NOMYDIMS) + return pdl_make_error(PDL_EUSERERROR, + "Error in %s: input parameter '%s' is null\n", + vtable->name, vtable->par_names[i] + ); if (ninds > 0 && ndims < ninds) { /* Dimensional promotion when number of dims is less than required: */ for (j=0; j pp_line_numbers(__LINE__-1, ' +sub PDL::append { + my ($i1, $i2, $o) = map PDL->topdl($_), @_; + if (grep $_->isempty, $i1, $i2) { + if (!defined $o) { + return $i2->copy if $i1->isempty; + return $i1->isnull ? PDL->zeroes(0) : $i1->copy; + } else { + $o .= $i2->isnull ? PDL->zeroes(0) : $i2, return $o if $i1->isempty; + $o .= $i1->isnull ? PDL->zeroes(0) : $i1, return $o; + } + } + $o //= PDL->null; + PDL::_append_int($i1, $i2, $o); + $o; +} + '), RedoDimsCode => ' pdl * dpdla = $PDL(a); pdl * dpdlb = $PDL(b); diff --git a/Changes b/Changes index dba2d7a41..b11ea6967 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,5 @@ - PDL::Complex no longer undefs PDL::i +- passing null as input param now an error 2.072 2022-01-30 - fix bug in qsortveci that broke PDL::VectorValued - thanks @zmughal for report diff --git a/t/01-pptest.t b/t/01-pptest.t index 54d9568cc..b203e8d76 100644 --- a/t/01-pptest.t +++ b/t/01-pptest.t @@ -129,6 +129,14 @@ pp_deft('fooseg', loop(n) %{ $b() = $a(); %} '); +# adapted from PDL::NDBin: if in=null and b is a scalar, was SEGV-ing +pp_deft( '_flatten_into', + Pars => "in(m); indx b(m); [o] idx(m)", + Code => ' + loop(m) %{ $idx() = $in(); %} + ', +); + pp_addhdr << 'EOH'; void tinplace_c1(int n, PDL_Float* data); void tinplace_c2(int n, PDL_Float* data1, PDL_Float* data2); @@ -300,16 +308,18 @@ is( join(',',$x->dims), "10" ); ok( tapprox($x,sequence(10)) ); # this used to segv under solaris according to Karl -{ no warnings 'uninitialized'; +{ my $ny=7; $x = double xvals zeroes (20,$ny); test_fooseg $x, $y=null; - ok( 1 ); # if we get here at all that is alright ok( tapprox($x,$y) ) or diag($x, "\n", $y); } +eval { test__flatten_into(null, 2) }; +ok 1; #was also segfaulting + # test the bug alluded to in the comments in # pdl_changed (pdlapi.c) # used to segfault diff --git a/t/core.t b/t/core.t index dfab4fbc9..9f31b2d2c 100644 --- a/t/core.t +++ b/t/core.t @@ -117,6 +117,14 @@ do { $x = pdl(pdl(5)); ok all( $x== pdl(5)), "pdl() can piddlify an ndarray"; +$x = pdl(null); +is_deeply [$x->dims], [0], 'pdl(null) gives empty' or diag "x(", $x->info, ")"; +ok !$x->isnull, 'pdl(null) gives non-null' or diag "x(", $x->info, ")"; + +$x = pdl(null, null); +is_deeply [$x->dims], [0,2], 'pdl(null, null) gives empty' or diag "x(", $x->info, ")"; +ok !$x->isnull, 'pdl(null, null) gives non-null' or diag "x(", $x->info, ")"; + # pdl of mixed-dim pdls: pad within a dimension $x = pdl( zeroes(5), ones(3) ); ok all($x == pdl([0,0,0,0,0],[1,1,1,0,0])),"Piddlifying two ndarrays concatenates them and pads to length" or diag("x=$x\n"); diff --git a/t/primitive.t b/t/primitive.t index 2acf2e1c9..540d4b0b1 100644 --- a/t/primitive.t +++ b/t/primitive.t @@ -293,6 +293,12 @@ ok($a1->at($x->list,$y->list,$z->list,$w->list) == 203, "whichND" ); $a1 = pdl(1,2,3,4); my $b1 = append($a1,2); ok(int(sum($b1))==12, "append"); +$b1 = append(null, null); +ok !$b1->isnull, 'append(null, null) returns non-null'; +ok $b1->isempty, 'append(null, null) returns an empty'; +append(null, null, $b1); +ok !$b1->isnull, 'append(null, null, b1) sets non-null'; +ok $b1->isempty, 'append(null, null, b1) sets an empty'; # clip tests ok(tapprox($im->hclip(5)->sum,83), "hclip" );