From: gfx Date: Fri, 26 Feb 2010 08:00:09 +0000 (+0900) Subject: Simplify error check routines in XS X-Git-Tag: 0.50_04~6 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMouse.git;a=commitdiff_plain;h=d06d926635763fa5687c429b5ad39938c564fbed Simplify error check routines in XS --- diff --git a/mouse.h b/mouse.h index e58d8ae..bfb7836 100644 --- a/mouse.h +++ b/mouse.h @@ -103,6 +103,12 @@ GV* mouse_stash_fetch(pTHX_ HV* const stash, const char* const name, I32 const n void mouse_install_sub(pTHX_ GV* const gv, SV* const code_ref); +void mouse_must_defined(pTHX_ SV* const value, const char* const name); +void mouse_must_ref(pTHX_ SV* const value, const char* const name, svtype const t); + +#define must_defined(sv, name) mouse_must_defined(aTHX_ sv, name) +#define must_ref(sv, name, svt) mouse_must_ref(aTHX_ sv, name, svt) + #define MOUSEf_DIE_ON_FAIL 0x01 MAGIC* mouse_mg_find(pTHX_ SV* const sv, const MGVTBL* const vtbl, I32 const flags); diff --git a/xs-src/Mouse.xs b/xs-src/Mouse.xs index f435464..e94d476 100644 --- a/xs-src/Mouse.xs +++ b/xs-src/Mouse.xs @@ -430,10 +430,7 @@ mouse_get_modifier_storage(pTHX_ SV* table; SV* storage_ref; - SvGETMAGIC(name); - if(!SvOK(name)){ - mouse_throw_error(meta, NULL, "You must define a method name for '%s' modifiers", keys[m]); - } + must_defined(name, "a method name"); table = get_slot(meta, key); @@ -512,24 +509,15 @@ CODE: croak("No package name defined"); } - SvGETMAGIC(name); - SvGETMAGIC(code); - - if(!SvOK(name)){ - mouse_throw_error(self, NULL, "You must define a method name"); - } - if(!SvROK(code)){ - mouse_throw_error(self, NULL, "You must define a CODE reference"); - } + must_defined(name, "a method name"); + must_ref (code, "a CODE reference", SVt_NULL); /* any reftype is OK */ code_ref = code; if(SvTYPE(SvRV(code_ref)) != SVt_PVCV){ SV* sv = code_ref; /* used in tryAMAGICunDEREF */ SV** sp = &sv; /* used in tryAMAGICunDEREF */ tryAMAGICunDEREF(to_cv); /* try \&{$code} */ - if(!(SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV)){ - mouse_throw_error(self, NULL, "You must pass a CODE reference to add_method"); - } + must_ref(code, "a CODE reference", SVt_PVCV); code_ref = sv; } @@ -793,8 +781,6 @@ CODE: SV* const meta = get_metaclass(self); AV* const xc = mouse_get_xc(aTHX_ meta); - if(!IsHashRef(args)){ - croak("You must pass a HASH reference to BUILDALL"); - } + must_ref(args, "a HASH reference to BUILDALL", SVt_PVHV); mouse_buildall(aTHX_ xc, self, args); } diff --git a/xs-src/MouseAttribute.xs b/xs-src/MouseAttribute.xs index 8ea3a06..617a99a 100644 --- a/xs-src/MouseAttribute.xs +++ b/xs-src/MouseAttribute.xs @@ -280,10 +280,7 @@ CODE: /* taken from Class::MOP::Attribute::new */ - if(!SvOK(name)){ - mouse_throw_error(klass, NULL, - "You must provide a name for the attribute"); - } + must_defined(name, "an attribute name"); svp = hv_fetchs(args, "init_arg", FALSE); if(!svp){ diff --git a/xs-src/MouseTypeConstraints.xs b/xs-src/MouseTypeConstraints.xs index 605c923..34ab1ea 100644 --- a/xs-src/MouseTypeConstraints.xs +++ b/xs-src/MouseTypeConstraints.xs @@ -530,10 +530,7 @@ mouse_generate_can_predicate_for(pTHX_ SV* const methods, const char* const pred I32 len; I32 i; - SvGETMAGIC(methods); - if(!IsArrayRef(methods)){ - croak("You must pass an ARRAY ref method names"); - } + must_ref(methods, "an ARRAY ref for method names", SVt_PVAV); av = (AV*)SvRV(methods); len = av_len(av) + 1; diff --git a/xs-src/MouseUtil.xs b/xs-src/MouseUtil.xs index aba91be..fad81d0 100644 --- a/xs-src/MouseUtil.xs +++ b/xs-src/MouseUtil.xs @@ -120,6 +120,30 @@ mouse_throw_error(SV* const metaobject, SV* const data /* not used */, const cha } } +void +mouse_must_defined(pTHX_ SV* const value, const char* const name) { + assert(value); + assert(name); + + SvGETMAGIC(value); + if(!SvOK(value)){ + croak("You must define %s", name); + } +} + +void +mouse_must_ref(pTHX_ SV* const value, const char* const name, svtype const t) { + assert(value); + assert(name); + + SvGETMAGIC(value); + if(!(SvROK(value) && (t == SVt_NULL || SvTYPE(SvRV(value)) == t))) { + croak("You must pass %s, not %s", + name, SvOK(value) ? SvPV_nolen(value) : "undef"); + } +} + + bool mouse_is_class_loaded(pTHX_ SV * const klass){ HV *stash; @@ -272,6 +296,7 @@ mouse_install_sub(pTHX_ GV* const gv, SV* const code_ref) { SvREFCNT_dec(GvCV(gv)); GvCV(gv) = NULL; } + sv_setsv_mg((SV*)gv, code_ref); /* *gv = $code_ref */ /* name the CODE ref if it's anonymous */ @@ -390,12 +415,8 @@ CODE: const char* name_pv; GV* gv; - if(!SvOK(package)){ - croak("You must define %s", "a package name"); - } - if(!SvOK(name)){ - croak("You must define %s", "a subroutine name"); - } + must_defined(package, "a package name"); + must_defined(name, "a subroutine name"); stash = gv_stashsv(package, FALSE); if(!stash){ @@ -423,17 +444,10 @@ PPCODE: const char* name_pv = NULL; CV* xsub; - SvGETMAGIC(arg); - - if(!SvOK(arg)){ - croak("You must define %s", ix == 0 ? "a class name" : "method names"); - } + must_defined(arg, ix == 0 ? "a class_name" : "method names"); if(predicate_name){ - SvGETMAGIC(predicate_name); - if(!SvOK(predicate_name)){ - croak("You must define %s", "a predicate name"); - } + must_defined(predicate_name, "a predicate name"); name_pv = SvPV_nolen_const(predicate_name); } @@ -457,10 +471,7 @@ CODE: HV* stash; I32 i; - SvGETMAGIC(into); - if(!SvOK(into)){ - croak("You must define %s", "a package name"); - } + must_defined(into, "a package name"); stash = gv_stashsv(into, TRUE); if( ((items-1) % 2) != 0 ){ @@ -474,14 +485,8 @@ CODE: const char* pv; GV* gv; - SvGETMAGIC(name); - if(!SvOK(name)){ - croak("You must define %s", "a subroutine name"); - } - SvGETMAGIC(code); - if(!IsCodeRef(code)){ - croak("You must define %s", "a CODE reference"); - } + must_defined(name, "a subroutine name"); + must_ref(code, "a CODE reference", SVt_PVCV); pv = SvPV_const(name, len); gv = stash_fetch(stash, pv, len, TRUE);