Blob Blame History Raw
From 19760e5b97136de3474743db8f2ae86380658f82 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 12 Jul 2017 15:53:20 -0500
Subject: [PATCH] Refactor: libcrmcommon,etc.: convenience functions for string
 tables

A simple hash table of dynamically allocated strings is the most common type in
the code base. This adds convenience functions for regular and case-insensitive
table creation, which makes the code less ugly, hopefully without sacrificing
readability.

As a side effect, this gets rid of a lot of usage of g_hash_destroy_str() when
we only need free().
---
 include/crm/common/util.h | 32 ++++++++++++++++++++++++++++++++
 include/crm/crm.h         |  5 -----
 lib/common/strings.c      | 20 ++++++++++++++++++++
 3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/include/crm/common/util.h b/include/crm/common/util.h
index 904b40c..04f7c31 100644
--- a/include/crm/common/util.h
+++ b/include/crm/common/util.h
@@ -30,6 +30,7 @@
 #  include <limits.h>
 #  include <signal.h>
 #  include <sysexits.h>
+#  include <glib.h>
 
 #  include <crm/lrmd.h>
 
@@ -60,8 +61,11 @@ int crm_parse_int(const char *text, const char *default_text);
 char * crm_strip_trailing_newline(char *str);
 gboolean crm_str_eq(const char *a, const char *b, gboolean use_case);
 gboolean safe_str_neq(const char *a, const char *b);
+guint crm_strcase_hash(gconstpointer v);
+guint g_str_hash_traditional(gconstpointer v);
 
 #  define safe_str_eq(a, b) crm_str_eq(a, b, FALSE)
+#  define crm_str_hash g_str_hash_traditional
 
 /* used with hash tables where case does not matter */
 static inline gboolean
@@ -70,6 +74,34 @@ crm_strcase_equal(gconstpointer a, gconstpointer b)
     return crm_str_eq((const char *) a, (const char *) b, FALSE);
 }
 
+/*!
+ * \brief Create hash table with dynamically allocated string keys/values
+ *
+ * \return Newly hash table
+ * \note It is the caller's responsibility to free the result, using
+ *       g_hash_table_destroy().
+ */
+static inline GHashTable *
+crm_str_table_new()
+{
+    return g_hash_table_new_full(crm_str_hash, g_str_equal, free, free);
+}
+
+/*!
+ * \brief Create hash table with case-insensitive dynamically allocated string keys/values
+ *
+ * \return Newly hash table
+ * \note It is the caller's responsibility to free the result, using
+ *       g_hash_table_destroy().
+ */
+static inline GHashTable *
+crm_strcase_table_new()
+{
+    return g_hash_table_new_full(crm_strcase_hash, crm_strcase_equal, free, free);
+}
+
+GHashTable *crm_str_table_dup(GHashTable *old_table);
+
 #  define crm_atoi(text, default_text) crm_parse_int(text, default_text)
 
 /* public I/O functions (from io.c) */
diff --git a/include/crm/crm.h b/include/crm/crm.h
index d03bcf2..0da6bfe 100644
--- a/include/crm/crm.h
+++ b/include/crm/crm.h
@@ -208,11 +208,6 @@ typedef GList *GListPtr;
 #  include <crm/common/util.h>
 #  include <crm/error.h>
 
-#  define crm_str_hash g_str_hash_traditional
-
-guint crm_strcase_hash(gconstpointer v);
-guint g_str_hash_traditional(gconstpointer v);
-
 static inline const char *crm_action_str(const char *task, int interval) {
     if(safe_str_eq(task, RSC_STATUS) && !interval) {
         return "probe";
diff --git a/lib/common/strings.c b/lib/common/strings.c
index 3df41f6..c624b4b 100644
--- a/lib/common/strings.c
+++ b/lib/common/strings.c
@@ -288,6 +288,26 @@ crm_strcase_hash(gconstpointer v)
     return h;
 }
 
+static void
+copy_str_table_entry(gpointer key, gpointer value, gpointer user_data)
+{
+    if (key && value && user_data) {
+        g_hash_table_insert((GHashTable*)user_data, strdup(key), strdup(value));
+    }
+}
+
+GHashTable *
+crm_str_table_dup(GHashTable *old_table)
+{
+    GHashTable *new_table = NULL;
+
+    if (old_table) {
+        new_table = crm_str_table_new();
+        g_hash_table_foreach(old_table, copy_str_table_entry, new_table);
+    }
+    return new_table;
+}
+
 char *
 add_list_element(char *list, const char *value)
 {
-- 
1.8.3.1