diff options
author | Yves Orton <demerphq@gmail.com> | 2006-02-13 12:39:33 +0100 |
---|---|---|
committer | Steve Peters <steve@fisharerojo.org> | 2006-02-14 17:08:08 +0000 |
commit | 96c33d98b34ca8475e06ac046725bba9fb34e6b6 (patch) | |
tree | 81aa4f4f1932c1589b7a296474963a02b5c9aa9e /ext/Hash/Util/Util.xs | |
parent | cbae9b9ff8bcf8bd286fe05ec47b85b49a5edee5 (diff) | |
download | perl-96c33d98b34ca8475e06ac046725bba9fb34e6b6.tar.gz |
[Patch] Enhance Hash::Util
Message-ID: <9b18b3110602130239w311d05fcr776ae8333776ca2e@mail.gmail.com>
p4raw-id: //depot/perl@27180
Diffstat (limited to 'ext/Hash/Util/Util.xs')
-rw-r--r-- | ext/Hash/Util/Util.xs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/ext/Hash/Util/Util.xs b/ext/Hash/Util/Util.xs new file mode 100644 index 0000000000..4d7c964b42 --- /dev/null +++ b/ext/Hash/Util/Util.xs @@ -0,0 +1,113 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + + +MODULE = Hash::Util PACKAGE = Hash::Util + + +SV* +all_keys(hash,keys,placeholder) + SV* hash + SV* keys + SV* 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); + + (void)hv_iterinit(hv); + while((he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS))!= NULL) { + key=hv_iterkeysv(he); + if (HeVAL(he) == &PL_sv_placeholder) { + SvREFCNT_inc(key); + av_push(av_p, key); + } else { + SvREFCNT_inc(key); + av_push(av_k, key); + } + } + RETVAL=hash; + + +void +hidden_ref_keys(hash) + SV* 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) { + key=hv_iterkeysv(he); + if (HeVAL(he) == &PL_sv_placeholder) { + XPUSHs( key ); + } + } + +void +legal_ref_keys(hash) + SV* 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) { + key=hv_iterkeysv(he); + XPUSHs( key ); + } + +SV* +hv_store(hvref, key, val) + SV* hvref + SV* key + SV* val + PROTOTYPE: \%$$ + PREINIT: + HV* hv; + CODE: + { + if (!SvROK(hvref) || SvTYPE(SvRV(hvref)) != SVt_PVHV) + croak("First argument to alias_hv() must be a hash reference"); + hv = (HV*)SvRV(hvref); + SvREFCNT_inc(val); + if (!hv_store_ent(hv, key, val, 0)) { + SvREFCNT_dec(val); + XSRETURN_NO; + } else { + XSRETURN_YES; + } + + } + OUTPUT: + RETVAL
\ No newline at end of file |