From bb2207048575f11637b495e7a5c5ab05537cf10e Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Tue, 17 Jan 2017 16:09:11 -0800 Subject: [PATCH] Add casecmp and strdup_key flags to hash_create() Aliases and (in the future), X-Label hashes will require a hash that strdups the key. Convert the casecmp parameter of hash_create() to a flags parameter, and add a flag to strdup the keys. --- hash.c | 14 ++++++++++---- hash.h | 5 +++++ init.c | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/hash.c b/hash.c index 457acfe79..d0a954fdc 100644 --- a/hash.c +++ b/hash.c @@ -79,7 +79,7 @@ static int cmp_int_key (union hash_key a, union hash_key b) static HASH *new_hash (int nelem) { - HASH *table = safe_malloc (sizeof (HASH)); + HASH *table = safe_calloc (1, sizeof (HASH)); if (nelem == 0) nelem = 2; table->nelem = nelem; @@ -88,10 +88,10 @@ static HASH *new_hash (int nelem) return table; } -HASH *hash_create (int nelem, int lower) +HASH *hash_create (int nelem, int flags) { HASH *table = new_hash (nelem); - if (lower) + if (flags & MUTT_HASH_STRCASECMP) { table->gen_hash = gen_case_string_hash; table->cmp_key = cmp_case_string_key; @@ -101,6 +101,8 @@ HASH *hash_create (int nelem, int lower) table->gen_hash = gen_string_hash; table->cmp_key = cmp_string_key; } + if (flags & MUTT_HASH_STRDUP_KEYS) + table->strdup_keys = 1; return table; } @@ -185,7 +187,7 @@ static int union_hash_insert (HASH * table, union hash_key key, void *data, int int hash_insert (HASH * table, const char *strkey, void *data, int allow_dup) { union hash_key key; - key.strkey = strkey; + key.strkey = table->strdup_keys ? safe_strdup (strkey) : strkey; return union_hash_insert (table, key, data, allow_dup); } @@ -279,6 +281,8 @@ static void union_hash_delete (HASH *table, union hash_key key, const void *data *last = ptr->next; if (destroy) destroy (ptr->data); + if (table->strdup_keys) + FREE (&ptr->key.strkey); FREE (&ptr); table->curnelem--; @@ -329,6 +333,8 @@ void hash_destroy (HASH **ptr, void (*destroy) (void *)) elem = elem->next; if (destroy) destroy (tmp->data); + if (pptr->strdup_keys) + FREE (&tmp->key.strkey); FREE (&tmp); } } diff --git a/hash.h b/hash.h index 455e3a19f..db5006a21 100644 --- a/hash.h +++ b/hash.h @@ -35,12 +35,17 @@ struct hash_elem typedef struct { int nelem, curnelem; + int strdup_keys; /* if set, the key->strkey is strdup'ed */ struct hash_elem **table; unsigned int (*gen_hash)(union hash_key, unsigned int); int (*cmp_key)(union hash_key, union hash_key); } HASH; +/* flags for hash_create() */ +#define MUTT_HASH_STRCASECMP (1<<0) /* use strcasecmp() to compare keys */ +#define MUTT_HASH_STRDUP_KEYS (1<<1) /* make a copy of the keys */ + HASH *hash_create (int nelem, int lower); HASH *int_hash_create (int nelem); diff --git a/init.c b/init.c index 8637beb4d..0448c952b 100644 --- a/init.c +++ b/init.c @@ -3554,7 +3554,7 @@ void mutt_init (int skip_sys_rc, LIST *commands) err.dptr = err.data; Groups = hash_create (1031, 0); - ReverseAlias = hash_create (1031, 1); + ReverseAlias = hash_create (1031, MUTT_HASH_STRCASECMP); #ifdef USE_NOTMUCH TagTransforms = hash_create (64, 1); TagFormats = hash_create (64, 0); -- 2.40.0