]> granicus.if.org Git - mutt/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)
committerKevin McCarthy <kevin@8t8.us>
Wed, 18 Jan 2017 00:09:11 +0000 (16:09 -0800)
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 bbe316290a8c3368f67b161fe710b9f2b69f645a..c8dbaeba2a6bcd4d104e0b88c5acdb5fce653c17 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;
@@ -87,10 +87,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;
@@ -100,6 +100,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;
 }
 
@@ -159,7 +161,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);
 }
 
@@ -236,6 +238,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);
 
       ptr = *last;
@@ -285,6 +289,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 60dc63940c804732f1b6a721a70d7871d895164f..3aa5b60514feb454d7a0db5e9010d2f4afc85610 100644 (file)
--- a/hash.h
+++ b/hash.h
@@ -35,12 +35,17 @@ struct hash_elem
 typedef struct
 {
   int nelem;
+  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 60d74135a3c6634f8e01333a304dbacded983276..7f16d59175093b3468953fa029349bb1601cba1a 100644 (file)
--- a/init.c
+++ b/init.c
@@ -3158,7 +3158,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);
   
   mutt_menu_init ();
   mutt_srandom ();