STATIC U16 vmg_wizard_sig(pTHX_ SV *wiz) {
#define vmg_wizard_sig(W) vmg_wizard_sig(aTHX_ (W))
- char buf[8];
U16 sig;
if (SvROK(wiz)) {
{
dMY_CXT;
- if (!hv_exists(MY_CXT.wizards, buf, sprintf(buf, "%u", sig)))
+ char buf[8];
+ SV **old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0);
+ if (!(old && SV2MGWIZ(*old)))
croak(vmg_invalid_wiz);
}
STATIC SV *vmg_wizard_wiz(pTHX_ SV *wiz) {
#define vmg_wizard_wiz(W) vmg_wizard_wiz(aTHX_ (W))
- char buf[8];
- SV **old;
U16 sig;
if (SvROK(wiz)) {
{
dMY_CXT;
- return (old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0))
- ? *old : NULL;
+ char buf[8];
+ SV **old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0);
+ if (!(old && SV2MGWIZ(*old)))
+ croak(vmg_invalid_wiz);
+
+ return *old;
}
}
STRLEN len;
char *sig = HePV(key, len);
SV *sv;
- const MGWIZ *w;
- MAGIC *mg;
- w = SV2MGWIZ(HeVAL(key));
- w = vmg_wizard_clone(w);
- sv = MGWIZ2SV(w);
- mg = sv_magicext(sv, NULL, PERL_MAGIC_ext, &vmg_wizard_vtbl, NULL, 0);
- mg->mg_private = SIG_WZO;
+ const MGWIZ *w = SV2MGWIZ(HeVAL(key));
+ if (w) {
+ MAGIC *mg;
+ w = vmg_wizard_clone(w);
+ sv = MGWIZ2SV(w);
+ mg = sv_magicext(sv, NULL, PERL_MAGIC_ext, &vmg_wizard_vtbl, NULL, 0);
+ mg->mg_private = SIG_WZO;
+ } else {
+ sv = MGWIZ2SV(NULL);
+ }
SvREADONLY_on(sv);
if (!hv_store(hv, sig, len, sv, HeHASH(key))) croak("%s during CLONE", vmg_globstorefail);
}
if (SvOK(svsig)) {
SV **old;
sig = vmg_sv2sig(svsig);
- if ((old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0))) {
+ old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0);
+ if (old && SV2MGWIZ(*old)) {
ST(0) = sv_2mortal(newRV_inc(*old));
XSRETURN(1);
}
SV *gensig()
PROTOTYPE:
+PREINIT:
+ U16 sig;
+ char buf[8];
CODE:
- RETVAL = newSVuv(vmg_gensig());
+ dMY_CXT;
+ sig = vmg_gensig();
+ if (!hv_store(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), MGWIZ2SV(NULL), 0)) croak(vmg_globstorefail);
+ RETVAL = newSVuv(sig);
OUTPUT:
RETVAL
SV *ret;
CODE:
wiz = vmg_wizard_wiz(wiz);
- if (!wiz)
- XSRETURN_UNDEF;
if (items > 2) {
I32 i;
args = newAV();
use strict;
use warnings;
-use Test::More tests => 46;
+use Test::More tests => 48;
use Variable::Magic qw/wizard gensig getsig cast dispell MGf_COPY MGf_DUP MGf_LOCAL VMG_UVAR/;
+my $inv_wiz_obj = qr/Invalid\s+wizard\s+object\s+at\s+\Q$0\E/;
+
my $args = 8;
++$args if MGf_COPY;
++$args if MGf_DUP;
my $sig = gensig;
+my $a = 1;
+my $res = eval { cast $a, $sig };
+like($@, $inv_wiz_obj, 'cast from wrong sig croaks');
+is($res, undef, 'cast from wrong sig doesn\'t return anything');
+
my $wiz = eval { wizard sig => $sig };
is($@, '', 'wizard doesn\'t croak');
ok(defined $wiz, 'wizard is defined');
is(ref $wiz, 'SCALAR', 'wizard is a scalar ref');
is($sig, getsig $wiz, 'wizard signature is correct');
-my $a = 1;
-my $res = eval { cast $a, $wiz };
+$res = eval { cast $a, $wiz };
is($@, '', 'cast doesn\'t croak');
ok($res, 'cast is valid');
ok($res, 're-cast is valid');
$res = eval { dispell $a, gensig };
-like($@, qr/Invalid\s+wizard\s+object\s+at\s+\Q$0\E/, 're-dispell from wrong sig croaks');
-is($res, undef, 're-dispell from wrong sig doesn\'t return anything');
+like($@, $inv_wiz_obj, 're-dispell from wrong sig croaks');
+is($res, undef, 're-dispell from wrong sig doesn\'t return anything');
$res = eval { dispell $a, undef };
-like($@, qr/Invalid\s+wizard\s+object\s+at\s+\Q$0\E/, 're-dispell from undef croaks');
-is($res, undef, 're-dispell from undef doesn\'t return anything');
+like($@, $inv_wiz_obj, 're-dispell from undef croaks');
+is($res, undef, 're-dispell from undef doesn\'t return anything');
$res = eval { dispell $a, $sig };
is($@, '', 're-dispell from good sig doesn\'t croak');
}
my $c = 3;
$res = eval { cast $c, $sig };
-is($@, '', 'cast from obsolete signature doesn\'t croak');
-is($res, undef, 'cast from obsolete signature returns undef');
+like($@, $inv_wiz_obj, 'cast from obsolete signature croaks');
+is($res, undef, 'cast from obsolete signature returns undef');
$res = eval { cast $c, undef };
-like($@, qr/Invalid\s+wizard\s+object\s+at\s+\Q$0\E/, 'cast from undef croaks');
-is($res, undef, 'cast from undef doesn\'t return anything');
+like($@, $inv_wiz_obj, 'cast from undef croaks');
+is($res, undef, 'cast from undef doesn\'t return anything');