summaryrefslogtreecommitdiff
path: root/src/lib/libast/hash/hashdump.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
commit3950ffe2a485479f6561c27364d3d7df5a21d124 (patch)
tree468c6e14449d1b1e279222ec32f676b0311917d2 /src/lib/libast/hash/hashdump.c
downloadksh-upstream.tar.gz
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libast/hash/hashdump.c')
-rw-r--r--src/lib/libast/hash/hashdump.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/lib/libast/hash/hashdump.c b/src/lib/libast/hash/hashdump.c
new file mode 100644
index 0000000..3c2829a
--- /dev/null
+++ b/src/lib/libast/hash/hashdump.c
@@ -0,0 +1,173 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * dump HASH_* flags
+ */
+
+static void
+dumpflags(register int flags)
+{
+ if (flags & HASH_ALLOCATE) sfprintf(sfstderr, "allocate ");
+ if (flags & HASH_BUCKET) sfprintf(sfstderr, "bucket ");
+ if (flags & HASH_FIXED) sfprintf(sfstderr, "fixed ");
+ if (flags & HASH_HASHED) sfprintf(sfstderr, "hashed ");
+ if (flags & HASH_RESIZE) sfprintf(sfstderr, "resize ");
+ if (flags & HASH_STATIC) sfprintf(sfstderr, "static ");
+ if (flags & HASH_VALUE) sfprintf(sfstderr, "value ");
+}
+
+/*
+ * dump hash table bucket info
+ */
+
+static void
+dumpbucket(register Hash_table_t* tab, int flags)
+{
+ register Hash_bucket_t** sp;
+ register Hash_bucket_t* b;
+ Hash_bucket_t** sx;
+ int n;
+ unsigned char* s;
+
+ NoP(flags);
+ sx = tab->table + tab->size;
+ for (sp = tab->table; sp < sx; sp++)
+ {
+ n = 0;
+ for (b = *sp; b; b = b->next)
+ if (!(b->hash & HASH_DELETED) && (!(tab->flags & HASH_VALUE) || b->value))
+ n++;
+ if (n)
+ {
+ sfprintf(sfstderr, "%5d %2d :", sp - tab->table, n);
+ for (b = *sp; b; b = b->next)
+ if (!(b->hash & HASH_DELETED) && (!(tab->flags & HASH_VALUE) || b->value))
+ {
+ if (n = tab->root->namesize)
+ {
+ sfprintf(sfstderr, " 0x");
+ s = (unsigned char*)hashname(b);
+ while (n-- > 0)
+ sfprintf(sfstderr, "%02x", *s++);
+ }
+ else sfprintf(sfstderr, " %s", hashname(b));
+ if (b->hash & HASH_FLAGS)
+ {
+ sfprintf(sfstderr, "|");
+ if (b->hash & HASH_HIDES) sfprintf(sfstderr, "hides|");
+ if (b->hash & HASH_HIDDEN) sfprintf(sfstderr, "hidden|");
+ if (b->hash & HASH_KEEP) sfprintf(sfstderr, "keep|");
+ if (b->hash & HASH_OPAQUED) sfprintf(sfstderr, "opaque|");
+ }
+ if (tab->flags & HASH_VALUE) sfprintf(sfstderr, "=0x%08lx", (long)b->value);
+ }
+ sfprintf(sfstderr, "\n");
+ }
+ }
+ sfprintf(sfstderr, "\n");
+}
+
+/*
+ * dump info on a single table
+ */
+
+static void
+dumptable(register Hash_table_t* tab, register int flags)
+{
+ Hash_table_t* scope;
+ int level;
+
+ sfprintf(sfstderr, " name: %s", tab->name ? tab->name : "*no name*");
+ if (scope = tab->scope)
+ {
+ level = 1;
+ while (scope = scope->scope) level++;
+ sfprintf(sfstderr, " level %d scope on 0x%08lx", level, (unsigned long)tab->scope);
+ }
+ sfprintf(sfstderr, "\n");
+ sfprintf(sfstderr, " address: 0x%08lx\n", (unsigned long)tab);
+ sfprintf(sfstderr, " flags: ");
+ if (tab->frozen) sfprintf(sfstderr, "frozen=%d ", tab->frozen);
+ dumpflags(tab->flags);
+ sfprintf(sfstderr, "\n");
+ sfprintf(sfstderr, " size: %d\n", tab->size);
+ sfprintf(sfstderr, " buckets: %d\n", tab->buckets);
+ sfprintf(sfstderr, " bucketsize: %d\n", tab->bucketsize * sizeof(char*));
+ sfprintf(sfstderr, "\n");
+ if ((flags | tab->flags) & HASH_BUCKET) dumpbucket(tab, flags);
+}
+
+/*
+ * dump hash table root info
+ */
+
+static void
+dumproot(register Hash_root_t* root, register int flags)
+{
+ register Hash_table_t* tab;
+
+ sfprintf(sfstderr, " root\n");
+ sfprintf(sfstderr, " address: 0x%08lx\n", (unsigned long)root);
+ sfprintf(sfstderr, " flags: ");
+ dumpflags(root->flags);
+ if (root->namesize) sfprintf(sfstderr, "namesize=%d ", root->namesize);
+ if (root->local->alloc) sfprintf(sfstderr, "alloc=0x%08lx ", (unsigned long)root->local->alloc);
+ if (root->local->compare) sfprintf(sfstderr, "compare=0x%08lx ", (unsigned long)root->local->compare);
+ if (root->local->free) sfprintf(sfstderr, "free=0x%08lx ", (unsigned long)root->local->free);
+ if (root->local->hash) sfprintf(sfstderr, "hash=0x%08lx ", (unsigned long)root->local->hash);
+ if (root->local->region) sfprintf(sfstderr, "region=0x%08lx handle=0x%08lx ", (unsigned long)root->local->region, (unsigned long)root->local->handle);
+ sfprintf(sfstderr, "\n");
+ sfprintf(sfstderr, " meanchain: %d\n", root->meanchain);
+ sfprintf(sfstderr, " accesses: %d\n", root->accesses);
+ sfprintf(sfstderr, " collisions: %d\n", root->collisions);
+ sfprintf(sfstderr, "\n");
+ for (tab = root->references; tab; tab = tab->next)
+ dumptable(tab, flags);
+}
+
+/*
+ * dump hash table accounting info
+ * if tab is 0 then dump all tables in hash_info.list
+ * flags are HASH_* flags that specifiy optional dump info
+ */
+
+void
+hashdump(register Hash_table_t* tab, int flags)
+{
+ register Hash_root_t* root;
+
+ sfprintf(sfstderr, "\nhash table information:\n\n");
+ if (tab) dumproot(tab->root, flags);
+ else for (root = hash_info.list; root; root = root->next)
+ dumproot(root, flags);
+ sfsync(sfstderr);
+}