Skip to content

Commit 17cf168

Browse files
committed
perlxs.pod: update: CASE
Rewrite this section: =head3 The CASE: Keyword
1 parent 7188b4a commit 17cf168

File tree

1 file changed

+90
-44
lines changed

1 file changed

+90
-44
lines changed

dist/ExtUtils-ParseXS/lib/perlxs.pod

Lines changed: 90 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3866,50 +3866,96 @@ pointer.
38663866

38673867
=head3 The CASE: Keyword
38683868

3869-
The CASE: keyword allows an XSUB to have multiple distinct parts with each
3870-
part acting as a virtual XSUB. CASE: is greedy and if it is used then all
3871-
other XS keywords must be contained within a CASE:. This means nothing may
3872-
precede the first CASE: in the XSUB and anything following the last CASE: is
3873-
included in that case.
3874-
3875-
A CASE: might switch via a parameter of the XSUB, via the C<ix> ALIAS:
3876-
variable (see L<"The ALIAS: Keyword">), or maybe via the C<items> variable
3877-
(see L<"Ellipsis: variable-length parameter lists">). The last CASE: becomes the
3878-
B<default> case if it is not associated with a conditional. The following
3879-
example shows CASE switched via C<ix> with a function C<rpcb_gettime()>
3880-
having an alias C<x_gettime()>. When the function is called as
3881-
C<rpcb_gettime()> its parameters are the usual C<(char *host, time_t *timep)>,
3882-
but when the function is called as C<x_gettime()> its parameters are
3883-
reversed, C<(time_t *timep, char *host)>.
3884-
3885-
long
3886-
rpcb_gettime(a, b)
3887-
CASE: ix == 1
3888-
ALIAS:
3889-
x_gettime = 1
3890-
INPUT:
3891-
# 'a' is timep, 'b' is host
3892-
char *b
3893-
time_t a = NO_INIT
3894-
CODE:
3895-
RETVAL = rpcb_gettime(b, &a);
3896-
OUTPUT:
3897-
a
3898-
RETVAL
3899-
CASE:
3900-
# 'a' is host, 'b' is timep
3901-
char *a
3902-
time_t &b = NO_INIT
3903-
OUTPUT:
3904-
b
3905-
RETVAL
3906-
3907-
That function can be called with either of the following statements. Note
3908-
the different argument lists.
3909-
3910-
$status = rpcb_gettime($host, $timep);
3911-
3912-
$status = x_gettime($timep, $host);
3869+
int
3870+
foo(int a, int b = NO_INIT, int c = NO_INIT)
3871+
CASE: items == 1
3872+
C_ARGS: 0, a
3873+
CASE: items == 2
3874+
C_ARGS: b, a
3875+
CASE:
3876+
CODE:
3877+
RETVAL = b > c ? foo(b, a) : bar(b, a);
3878+
OUTPUT:
3879+
RETVAL
3880+
3881+
3882+
The C<CASE> keyword allows an XSUB to effectively have multiple bodies,
3883+
but with only a single Perl name (unlike C<ALIAS>, which has multiple
3884+
names). Which body is run depends on which CASE expression is the first to
3885+
evaluate to true. Unlike C's C<case> keyword, execution doesn't fall
3886+
though to the next branch, so there is no XS equivalent of the C<break>
3887+
keyword. The expression for the last CASE is optional, and if not present,
3888+
acts as a default branch.
3889+
3890+
The example above translates to approximately this C code:
3891+
3892+
if (items < 1 || items > 3) { croak("..."); }
3893+
3894+
if (items == 1) {
3895+
int RETVAL;
3896+
int a = (int)SvIV(ST(0)); int b = /* etc */
3897+
RETVAL = foo(0, a);
3898+
/* ... return RETVAL as ST(0) ... */
3899+
}
3900+
else if (items == 2) {
3901+
int RETVAL;
3902+
int a = (int)SvIV(ST(0)); int b = /* etc */
3903+
RETVAL = foo(b, a);
3904+
/* ... return RETVAL as ST(0) ... */
3905+
}
3906+
else {
3907+
int RETVAL;
3908+
int a = (int)SvIV(ST(0)); int b = /* etc */
3909+
RETVAL = b > c ? foo(b, a) : bar(b, a);
3910+
/* ... return RETVAL as ST(0) ... */
3911+
}
3912+
3913+
XSRETURN(1);
3914+
3915+
Each C<CASE> keyword precedes an entire normal XSUB body, including all
3916+
keywords from C<PREINIT> to C<CLEANUP>. Generic XSUB keywords can be
3917+
placed within any C<CASE> body. The code generated for each C<if>/C<else>
3918+
branch includes nearly all the code that would usually be generated for a
3919+
complete XSUB body, including argument processing and return value
3920+
stack processing.
3921+
3922+
Note that the CASE expressions are outside of the scope of any parameter
3923+
variable declarations, so those values can't be used. Typical values which
3924+
I<are> in scope and might be used are the C<items> variable which
3925+
indicates how many arguments were passed (see L<"Ellipsis: variable-length
3926+
parameter lists">) and, in the presence of C<ALIAS>, the C<ix> variable.
3927+
3928+
Here's another example, this time in conjunction with C<ALIAS> to wrap the
3929+
same C function as two separate Perl functions, the second of which
3930+
(perhaps for backwards compatibility reasons) takes its arguments in the
3931+
reverse order. This is a somewhat contrived example, but
3932+
demonstrates how the C<ALIAS> keyword must be within one of the C<CASE>
3933+
branches (it doesn't matter which), as C<CASE> must always appear in the
3934+
outermost scope of the XSUB's body:
3935+
3936+
int
3937+
foo(int a, int b)
3938+
CASE: ix == 0
3939+
CASE: ix == 1
3940+
ALIAS: foo_rev = 1
3941+
C_ARGS: b, a
3942+
3943+
Note that using old-style parameter declarations in conjunction with
3944+
C<INPUT> allows the types of the parameters to vary between branches:
3945+
3946+
int
3947+
foo(a, int b = 0)
3948+
CASE: items == 1
3949+
INPUT:
3950+
short a
3951+
CASE: items == 2
3952+
INPUT:
3953+
long a
3954+
3955+
In practice, C<CASE> produces bloated code with all the argument and
3956+
return value processing duplicated within each branch, is not often all
3957+
that useful, and can often be better written just by using a C<switch>
3958+
statement within a C<CODE> block.
39133959

39143960
=head2 Using Typemaps
39153961

0 commit comments

Comments
 (0)