Convert Hash::Util's XS code to use typemaps for dereferencing.
authorNicholas Clark <nick@ccl4.org>
Wed, 20 Oct 2010 16:41:57 +0000 (18:41 +0200)
committerNicholas Clark <nick@ccl4.org>
Thu, 21 Oct 2010 06:42:22 +0000 (08:42 +0200)
This will subtly change the text of the parameter mismatch errors.

ext/Hash-Util/Util.xs

index 03b049f..e65f428 100644 (file)
@@ -6,62 +6,41 @@
 MODULE = Hash::Util            PACKAGE = Hash::Util
 
 
-SV*
+void
 all_keys(hash,keys,placeholder)
-       SV* hash
-       SV* keys
-       SV* placeholder
+       HV *hash
+       AV *keys
+       AV *placeholder
     PROTOTYPE: \%\@\@
     PREINIT:
-       AV* av_k;
-        AV* av_p;
-        HV* hv;
         SV *key;
         HE *he;
-    CODE:
-       if (!SvROK(hash) || SvTYPE(SvRV(hash)) != SVt_PVHV)
-          croak("First argument to all_keys() must be an HASH reference");
-       if (!SvROK(keys) || SvTYPE(SvRV(keys)) != SVt_PVAV)
-          croak("Second argument to all_keys() must be an ARRAY reference");
-        if (!SvROK(placeholder) || SvTYPE(SvRV(placeholder)) != SVt_PVAV)
-          croak("Third argument to all_keys() must be an ARRAY reference");
-
-       hv = (HV*)SvRV(hash);
-       av_k = (AV*)SvRV(keys);
-       av_p = (AV*)SvRV(placeholder);
-
-        av_clear(av_k);
-        av_clear(av_p);
+    PPCODE:
+        av_clear(keys);
+        av_clear(placeholder);
 
-        (void)hv_iterinit(hv);
-       while((he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS))!= NULL) {
+        (void)hv_iterinit(hash);
+       while((he = hv_iternext_flags(hash, HV_ITERNEXT_WANTPLACEHOLDERS))!= NULL) {
            key=hv_iterkeysv(he);
             if (HeVAL(he) == &PL_sv_placeholder) {
                 SvREFCNT_inc(key);
-               av_push(av_p, key);
+               av_push(placeholder, key);
             } else {
                 SvREFCNT_inc(key);
-               av_push(av_k, key);
+               av_push(keys, key);
             }
         }
-        RETVAL=hash;
-
+       XSRETURN(1);
 
 void
 hidden_ref_keys(hash)
-       SV* hash
+       HV *hash
     PREINIT:
-        HV* hv;
         SV *key;
         HE *he;
     PPCODE:
-       if (!SvROK(hash) || SvTYPE(SvRV(hash)) != SVt_PVHV)
-          croak("First argument to hidden_keys() must be an HASH reference");
-
-       hv = (HV*)SvRV(hash);
-
-        (void)hv_iterinit(hv);
-       while((he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS))!= NULL) {
+        (void)hv_iterinit(hash);
+       while((he = hv_iternext_flags(hash, HV_ITERNEXT_WANTPLACEHOLDERS))!= NULL) {
            key=hv_iterkeysv(he);
             if (HeVAL(he) == &PL_sv_placeholder) {
                 XPUSHs( key );
@@ -70,42 +49,30 @@ hidden_ref_keys(hash)
 
 void
 legal_ref_keys(hash)
-       SV* hash
+       HV *hash
     PREINIT:
-        HV* hv;
         SV *key;
         HE *he;
     PPCODE:
-       if (!SvROK(hash) || SvTYPE(SvRV(hash)) != SVt_PVHV)
-          croak("First argument to legal_keys() must be an HASH reference");
-
-       hv = (HV*)SvRV(hash);
-
-        (void)hv_iterinit(hv);
-       while((he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS))!= NULL) {
+        (void)hv_iterinit(hash);
+       while((he = hv_iternext_flags(hash, HV_ITERNEXT_WANTPLACEHOLDERS))!= NULL) {
            key=hv_iterkeysv(he);
             XPUSHs( key );
         }
 
 void
-hv_store(hvref, key, val)
-       SV* hvref
+hv_store(hash, key, val)
+       HV *hash
        SV* key
        SV* val
     PROTOTYPE: \%$$
-    PREINIT:
-       HV* hv;
     CODE:
     {
-       if (!SvROK(hvref) || SvTYPE(SvRV(hvref)) != SVt_PVHV)
-          croak("First argument to hv_store() must be a HASH reference");
-       hv = (HV*)SvRV(hvref);
         SvREFCNT_inc(val);
-       if (!hv_store_ent(hv, key, val, 0)) {
+       if (!hv_store_ent(hash, key, val, 0)) {
            SvREFCNT_dec(val);
            XSRETURN_NO;
        } else {
            XSRETURN_YES;
        }
     }
-