diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-07-14 18:42:02 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-07-14 18:47:09 +0300 |
commit | 66eb071ce6202a33dbf53dfc46e52b25d683290c (patch) | |
tree | 87071ed312a385ee80385a4bd3aaf0d3641dc9d2 /src/gdbmtool.c | |
parent | 53c69f57651d0932632b45d5ee58f507575bb513 (diff) | |
download | gdbm-66eb071ce6202a33dbf53dfc46e52b25d683290c.tar.gz gdbm-66eb071ce6202a33dbf53dfc46e52b25d683290c.tar.bz2 |
gdbmtool: improve bucket dump and hash calculator
* src/gdbmtool.c (format_key_start): New function.
(print_bucket): Take variadic arguments, use mesg
as prinf-style format.
Display first bytes of each non-empty key.
(print_current_bucket_begin): Avoid coredump if
gdbm_file is not initialized.
(print_current_bucket_handler): Change header depending on the
invoking command.
(hash_handler): In presence of a database, print also the
bucket number and offset within the bucket.
Diffstat (limited to 'src/gdbmtool.c')
-rw-r--r-- | src/gdbmtool.c | 88 |
1 files changed, 67 insertions, 21 deletions
diff --git a/src/gdbmtool.c b/src/gdbmtool.c index 520d912..a7f7363 100644 --- a/src/gdbmtool.c +++ b/src/gdbmtool.c @@ -131,25 +131,54 @@ bucket_print_lines (hash_bucket *bucket) return 6 + gdbm_file->header->bucket_elems + 3 + bucket->av_count; } +static void +format_key_start (FILE *fp, bucket_element *elt) +{ + int size = SMALL < elt->key_size ? SMALL : elt->key_size; + int i; + + for (i = 0; i < size; i++) + { + if (isprint (elt->key_start[i])) + fprintf (fp, " %c", elt->key_start[i]); + else + fprintf (fp, " %03o", elt->key_start[i]); + } +} + /* Debug procedure to print the contents of the current hash bucket. */ void -print_bucket (FILE *fp, hash_bucket *bucket, const char *mesg) +print_bucket (FILE *fp, hash_bucket *bucket, const char *mesg, ...) { - int index; + int index; + va_list ap; + fprintf (fp, "******* "); + va_start(ap, mesg); + vfprintf (fp, mesg, ap); + va_end (ap); + fprintf (fp, " **********\n\n"); fprintf (fp, - _("******* %s **********\n\nbits = %d\ncount= %d\nHash Table:\n"), - mesg, bucket->bucket_bits, bucket->count); + _("bits = %d\ncount= %d\nHash Table:\n"), + bucket->bucket_bits, bucket->count); fprintf (fp, - _(" # hash value key size data size data adr home\n")); + _(" # hash value key size data size data adr home key start\n")); for (index = 0; index < gdbm_file->header->bucket_elems; index++) - fprintf (fp, " %4d %12x %11d %11d %11lu %5d\n", index, - bucket->h_table[index].hash_value, - bucket->h_table[index].key_size, - bucket->h_table[index].data_size, - (unsigned long) bucket->h_table[index].data_pointer, - bucket->h_table[index].hash_value % - gdbm_file->header->bucket_elems); + { + fprintf (fp, " %4d %12x %11d %11d %11lu %4d", index, + bucket->h_table[index].hash_value, + bucket->h_table[index].key_size, + bucket->h_table[index].data_size, + (unsigned long) bucket->h_table[index].data_pointer, + bucket->h_table[index].hash_value % + gdbm_file->header->bucket_elems); + if (bucket->h_table[index].key_size) + { + fprintf (fp, " "); + format_key_start (fp, &bucket->h_table[index]); + } + fprintf (fp, "\n"); + } fprintf (fp, _("\nAvail count = %1d\n"), bucket->av_count); fprintf (fp, _("Avail adr size\n")); @@ -526,20 +555,32 @@ print_current_bucket_begin (struct handler_param *param GDBM_ARG_UNUSED, { if (checkdb ()) return 1; - + if (!gdbm_file->bucket) + return 0; if (exp_count) - *exp_count = bucket_print_lines (gdbm_file->bucket) + 3; + *exp_count = gdbm_file->bucket + ? bucket_print_lines (gdbm_file->bucket) + 3 + : 1; return 0; } void print_current_bucket_handler (struct handler_param *param) { - print_bucket (param->fp, gdbm_file->bucket, _("Current bucket")); - fprintf (param->fp, _("\n current directory entry = %d.\n"), - gdbm_file->bucket_dir); - fprintf (param->fp, _(" current bucket address = %lu.\n"), - (unsigned long) gdbm_file->cache_entry->ca_adr); + if (!gdbm_file->bucket) + fprintf (param->fp, _("no current bucket\n")); + else + { + if (param->argc) + print_bucket (param->fp, gdbm_file->bucket, _("Bucket #%s"), + PARAM_STRING (param, 0)); + else + print_bucket (param->fp, gdbm_file->bucket, "%s", _("Current bucket")); + fprintf (param->fp, _("\n current directory entry = %d.\n"), + gdbm_file->bucket_dir); + fprintf (param->fp, _(" current bucket address = %lu.\n"), + (unsigned long) gdbm_file->cache_entry->ca_adr); + } } int @@ -652,8 +693,13 @@ print_header_handler (struct handler_param *param) void hash_handler (struct handler_param *param) { - fprintf (param->fp, _("hash value = %x. \n"), - _gdbm_hash (PARAM_DATUM (param, 0))); + int hashval = _gdbm_hash (PARAM_DATUM (param, 0)); + fprintf (param->fp, _("hash value = %x"), hashval); + if (gdbm_file) + fprintf (param->fp, _(", bucket #%u, slot %u"), + hashval >> (31 - gdbm_file->header->dir_bits), + hashval % gdbm_file->header->bucket_elems); + fprintf (param->fp, ".\n"); } /* cache - print the bucket cache */ |