]> granicus.if.org Git - neomutt/commitdiff
Add casecmp and strdup_key flags to hash_create()
authorKevin McCarthy <kevin@8t8.us>
Wed, 18 Jan 2017 00:09:11 +0000 (16:09 -0800)
committerRichard Russon <rich@flatcap.org>
Fri, 10 Feb 2017 03:32:55 +0000 (03:32 +0000)
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
hash.h
init.c

diff --git a/hash.c b/hash.c
index 457acfe79ed5fb42cd9695d109de8c8d8d9926b6..d0a954fdcde19f4bcfb489c82d785730ab31d600 100644 (file)
--- 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 455e3a19f35d3a3df8425da27efe28e128227b5f..db5006a214db6c1a0ec69aa3971a0b0eb04b96e9 100644 (file)
--- 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 8637beb4de9d76229b581e3ec6179d4a9ff4de01..0448c952b002af8d6981095dcf7cb694a5ea4eb8 100644 (file)
--- 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);