summaryrefslogtreecommitdiff
path: root/do/kv
diff options
context:
space:
mode:
Diffstat (limited to 'do/kv')
-rw-r--r--do/kv56
1 files changed, 56 insertions, 0 deletions
diff --git a/do/kv b/do/kv
new file mode 100644
index 0000000000..e433393947
--- /dev/null
+++ b/do/kv
@@ -0,0 +1,56 @@
+int
+do_kv(TARG,hash,kv,gimme,arglast)
+STR *TARG;
+HASH *hash;
+int kv;
+int gimme;
+int *arglast;
+{
+ register ARRAY *ary = stack;
+ STR **st = ary->ary_array;
+ register int sp = arglast[0];
+ int i;
+ register HENT *entry;
+ char *tmps;
+ STR *tmpstr;
+ int dokeys = (kv == O_KEYS || kv == O_HASH);
+ int dovalues = (kv == O_VALUES || kv == O_HASH);
+
+ if (gimme != G_ARRAY) {
+ i = 0;
+ (void)hiterinit(hash);
+ /*SUPPRESS 560*/
+ while (entry = hiternext(hash)) {
+ i++;
+ }
+ str_numset(TARG,(double)i);
+ STABSET(TARG);
+ st[++sp] = TARG;
+ return sp;
+ }
+ (void)hiterinit(hash);
+ /*SUPPRESS 560*/
+ while (entry = hiternext(hash)) {
+ if (dokeys) {
+ tmps = hiterkey(entry,&i);
+ if (!i)
+ tmps = "";
+ (void)astore(ary,++sp,str_2mortal(str_make(tmps,i)));
+ }
+ if (dovalues) {
+ tmpstr = Str_new(45,0);
+#ifdef DEBUGGING
+ if (debug & 8192) {
+ sprintf(buf,"%d%%%d=%d\n",entry->hent_hash,
+ hash->tbl_max+1,entry->hent_hash & hash->tbl_max);
+ str_set(tmpstr,buf);
+ }
+ else
+#endif
+ str_sset(tmpstr,hiterval(hash,entry));
+ (void)astore(ary,++sp,str_2mortal(tmpstr));
+ }
+ }
+ return sp;
+}
+