summaryrefslogtreecommitdiff
path: root/ext/Hash/Util/Util.xs
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2006-02-13 12:39:33 +0100
committerSteve Peters <steve@fisharerojo.org>2006-02-14 17:08:08 +0000
commit96c33d98b34ca8475e06ac046725bba9fb34e6b6 (patch)
tree81aa4f4f1932c1589b7a296474963a02b5c9aa9e /ext/Hash/Util/Util.xs
parentcbae9b9ff8bcf8bd286fe05ec47b85b49a5edee5 (diff)
downloadperl-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.xs113
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