Skip to content

Commit f16ca14

Browse files
committed
perlxs.pod: update: CASE
Rewrite this section: =head3 The CASE: Keyword
1 parent ce2509f commit f16ca14

File tree

1 file changed

+89
-44
lines changed

1 file changed

+89
-44
lines changed

dist/ExtUtils-ParseXS/lib/perlxs.pod

Lines changed: 89 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3825,50 +3825,95 @@ pointer.
38253825

38263826
=head3 The CASE: Keyword
38273827

3828-
The CASE: keyword allows an XSUB to have multiple distinct parts with each
3829-
part acting as a virtual XSUB. CASE: is greedy and if it is used then all
3830-
other XS keywords must be contained within a CASE:. This means nothing may
3831-
precede the first CASE: in the XSUB and anything following the last CASE: is
3832-
included in that case.
3833-
3834-
A CASE: might switch via a parameter of the XSUB, via the C<ix> ALIAS:
3835-
variable (see L<"The ALIAS: Keyword">), or maybe via the C<items> variable
3836-
(see L<"Ellipsis: variable-length parameter lists">). The last CASE: becomes the
3837-
B<default> case if it is not associated with a conditional. The following
3838-
example shows CASE switched via C<ix> with a function C<rpcb_gettime()>
3839-
having an alias C<x_gettime()>. When the function is called as
3840-
C<rpcb_gettime()> its parameters are the usual C<(char *host, time_t *timep)>,
3841-
but when the function is called as C<x_gettime()> its parameters are
3842-
reversed, C<(time_t *timep, char *host)>.
3843-
3844-
long
3845-
rpcb_gettime(a, b)
3846-
CASE: ix == 1
3847-
ALIAS:
3848-
x_gettime = 1
3849-
INPUT:
3850-
# 'a' is timep, 'b' is host
3851-
char *b
3852-
time_t a = NO_INIT
3853-
CODE:
3854-
RETVAL = rpcb_gettime(b, &a);
3855-
OUTPUT:
3856-
a
3857-
RETVAL
3858-
CASE:
3859-
# 'a' is host, 'b' is timep
3860-
char *a
3861-
time_t &b = NO_INIT
3862-
OUTPUT:
3863-
b
3864-
RETVAL
3865-
3866-
That function can be called with either of the following statements. Note
3867-
the different argument lists.
3868-
3869-
$status = rpcb_gettime($host, $timep);
3870-
3871-
$status = x_gettime($timep, $host);
3828+
int
3829+
foo(int a, int b = NO_INIT, int c = NO_INIT)
3830+
CASE: items == 1
3831+
C_ARGS: 0, a
3832+
CASE: items == 2
3833+
C_ARGS: b, a
3834+
CASE:
3835+
CODE:
3836+
RETVAL = b > c ? foo(b, a) : bar(b, a);
3837+
OUTPUT:
3838+
RETVAL
3839+
3840+
3841+
The C<CASE> keyword allows an XSUB to have multiple bodies with only a
3842+
single Perl name (unlike C<ALIAS>). Which body is run depends on which
3843+
CASE expression is the first to evaluate to true. Unlike C's C<case>
3844+
keyword, execution doesn't fall though to the next branch (so there is no
3845+
XS equivalent of the C<break> keyword). The expression for the last CASE
3846+
is optional, and if not present, acts as a default branch.
3847+
3848+
The example above translates to approximately this C code:
3849+
3850+
if (items < 1 || items > 3) { croak("..."); }
3851+
3852+
if (items == 1) {
3853+
int RETVAL;
3854+
int a = (int)SvIV(ST(0)); int b = /* etc */
3855+
RETVAL = foo(0, a);
3856+
/* ... return RETVAL as ST(0) ... */
3857+
}
3858+
else if (items == 2) {
3859+
int RETVAL;
3860+
int a = (int)SvIV(ST(0)); int b = /* etc */
3861+
RETVAL = foo(b, a);
3862+
/* ... return RETVAL as ST(0) ... */
3863+
}
3864+
else {
3865+
int RETVAL;
3866+
int a = (int)SvIV(ST(0)); int b = /* etc */
3867+
RETVAL = b > c ? foo(b, a) : bar(b, a);
3868+
/* ... return RETVAL as ST(0) ... */
3869+
}
3870+
3871+
XSRETURN(1);
3872+
3873+
Each C<CASE> keyword precedes an entire normal XSUB body, including all
3874+
keywords from C<PREINIT> to C<CLEANUP>. Generic XSUB keywords can be
3875+
placed within any C<CASE> body. The code generated for each C<if>/C<else>
3876+
branch includes nearly all the code that would usually be generated for a
3877+
complete XSUB body, including argument processing and return value
3878+
stack processing.
3879+
3880+
Note that the CASE expressions are outside of the scope of any parameter
3881+
variable declarations, so those values can't be used. Typical values which
3882+
I<are> in scope and might be used are the C<items> variable which
3883+
indicates how many arguments were passed (see L<"Ellipsis: variable-length
3884+
parameter lists">) and, in the presence of C<ALIAS>, the C<ix> variable.
3885+
3886+
Here's another example, this time in conjunction with C<ALIAS> to wrap the
3887+
same C function as two separate Perl functions, the second of which
3888+
(perhaps for backwards compatibility reasons) takes its arguments in the
3889+
reverse order. This is a somewhat contrived example, but
3890+
demonstrates how the C<ALIAS> keyword must be within one of the C<CASE>
3891+
branches (it doesn't matter which), as C<CASE> must always appear in the
3892+
outermost scope of the XSUB's body:
3893+
3894+
int
3895+
foo(int a, int b)
3896+
CASE: ix == 0
3897+
CASE: ix == 1
3898+
ALIAS: foo_rev = 1
3899+
C_ARGS: b, a
3900+
3901+
Note that using old-style parameter declarations in conjunction with
3902+
C<INPUT> allows the types of the parameters to vary between branches:
3903+
3904+
int
3905+
foo(a, int b = 0)
3906+
CASE: items == 1
3907+
INPUT:
3908+
short a
3909+
CASE: items == 2
3910+
INPUT:
3911+
long a
3912+
3913+
In practice, C<CASE> produces bloated code with all the argument and
3914+
return value processing duplicated within each branch, is not often all
3915+
that useful, and can often be better written just by using a C<switch>
3916+
statement within a C<CODE> block.
38723917

38733918
=head2 Using Typemaps
38743919

0 commit comments

Comments
 (0)