Skip to content

Commit a0f0d01

Browse files
committed
perlxs.pod: update: CASE
Rewrite this section: =head3 The CASE: Keyword
1 parent 683f8f4 commit a0f0d01

File tree

1 file changed

+81
-44
lines changed

1 file changed

+81
-44
lines changed

dist/ExtUtils-ParseXS/lib/perlxs.pod

Lines changed: 81 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,50 +3818,87 @@ pointer.
38183818

38193819
=head3 The CASE: Keyword
38203820

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

38663903
=head2 Using Typemaps
38673904

0 commit comments

Comments
 (0)