Skip to content

Commit

Permalink
Add test, and Cookbook example, of array-ref arg
Browse files Browse the repository at this point in the history
  • Loading branch information
mohawk2 authored and perlpunk committed May 4, 2019
1 parent a890092 commit cad7b4e
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
30 changes: 30 additions & 0 deletions doc/Inline/C/Cookbook.swim
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,36 @@ How do I pass a variable-sized list of arguments to an Inline C function?
( http://www.microship.com ), but he is close ( http://bike-nomad.com ). Thanks
Ned.

== Taking an array-ref as an argument

- Problem

How can I take a Perl array-ref as an argument in my C function?

- Solution

SV *sum(SV *array) {
int total = 0;
int numelts, i;
SvGETMAGIC(array);
if ((!SvROK(array))
|| (SvTYPE(SvRV(array)) != SVt_PVAV)
|| ((numelts = av_len((AV *)SvRV(array))) < 0)
) {
return &PL_sv_undef;
}
for (i = 0; i <= numelts; i++) {
total += SvIV(*av_fetch((AV *)SvRV(array), i, 0));
}
return newSViv(total);
}

- Discussion

This example returns `undef` if given a non-ref, or a non-array-ref,
or a ref to an empty array. You can see how you might expand this to
take more than one array-ref.

== Using Memory

- Problem
Expand Down
32 changes: 32 additions & 0 deletions test/29refargs.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use strict; use warnings;
use lib -e 't' ? 't' : 'test';
use diagnostics;
use TestInlineSetup;
use Inline Config => DIRECTORY => $TestInlineSetup::DIR;
use Test::More;

my $c_text = <<'EOC';
SV *sum(SV *array) {
int total = 0;
int numelts, i;
SvGETMAGIC(array);
if ((!SvROK(array))
|| (SvTYPE(SvRV(array)) != SVt_PVAV)
|| ((numelts = av_len((AV *)SvRV(array))) < 0)
) {
return &PL_sv_undef;
}
for (i = 0; i <= numelts; i++) {
total += SvIV(*av_fetch((AV *)SvRV(array), i, 0));
}
return newSViv(total);
}
EOC
Inline->bind(C => $c_text);

is sum([(1..4)]), 10, 'correct sum';
is sum(undef), undef, 'return undef when given undef';
is sum('hello'), undef, 'return undef when given non-ref';
is sum([]), undef, 'return undef when given empty list';

done_testing;

0 comments on commit cad7b4e

Please sign in to comment.