Blob Blame History Raw
From 45813df3eb4c8ad8b1744fa5dd56af86ad0fb3dd Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 17 Jun 2021 16:07:55 -0400
Subject: [PATCH] Refactor: libs: pcmk__str_in_list should support pcmk__str_*
 flags.

---
 include/crm/common/strings_internal.h |  2 +-
 lib/common/strings.c                  | 34 +++++++++++++++++++++++----
 lib/fencing/st_output.c               | 10 ++++----
 lib/pengine/bundle.c                  |  8 +++----
 lib/pengine/clone.c                   | 28 +++++++++++-----------
 lib/pengine/group.c                   | 18 +++++++-------
 lib/pengine/native.c                  |  4 ++--
 lib/pengine/pe_output.c               | 22 ++++++++---------
 lib/pengine/utils.c                   |  6 ++---
 9 files changed, 79 insertions(+), 53 deletions(-)

diff --git a/include/crm/common/strings_internal.h b/include/crm/common/strings_internal.h
index 94982cb4e..687079814 100644
--- a/include/crm/common/strings_internal.h
+++ b/include/crm/common/strings_internal.h
@@ -117,7 +117,7 @@ pcmk__intkey_table_remove(GHashTable *hash_table, int key)
     return g_hash_table_remove(hash_table, GINT_TO_POINTER(key));
 }
 
-gboolean pcmk__str_in_list(GList *lst, const gchar *s);
+gboolean pcmk__str_in_list(GList *lst, const gchar *s, uint32_t flags);
 
 bool pcmk__strcase_any_of(const char *s, ...) G_GNUC_NULL_TERMINATED;
 bool pcmk__str_any_of(const char *s, ...) G_GNUC_NULL_TERMINATED;
diff --git a/lib/common/strings.c b/lib/common/strings.c
index 3264db5b6..e1e98803b 100644
--- a/lib/common/strings.c
+++ b/lib/common/strings.c
@@ -872,14 +872,30 @@ pcmk__parse_ll_range(const char *srcstring, long long *start, long long *end)
  * Search \p lst for \p s, taking case into account.  As a special case,
  * if "*" is the only element of \p lst, the search is successful.
  *
- * \param[in]  lst  List to search
- * \param[in]  s    String to search for
+ * Behavior can be changed with various flags:
+ *
+ * - pcmk__str_casei - By default, comparisons are done taking case into
+ *                     account.  This flag makes comparisons case-insensitive.
+ * - pcmk__str_null_matches - If the input string is NULL, return TRUE.
+ *
+ * \note The special "*" matching rule takes precedence over flags.  In
+ *       particular, "*" will match a NULL input string even without
+ *       pcmk__str_null_matches being specified.
+ *
+ * \note No matter what input string or flags are provided, an empty
+ *       list will always return FALSE.
+ *
+ * \param[in]  lst   List to search
+ * \param[in]  s     String to search for
+ * \param[in]  flags A bitfield of pcmk__str_flags to modify operation
  *
  * \return \c TRUE if \p s is in \p lst, or \c FALSE otherwise
  */
 gboolean
-pcmk__str_in_list(GList *lst, const gchar *s)
+pcmk__str_in_list(GList *lst, const gchar *s, uint32_t flags)
 {
+    GCompareFunc fn;
+
     if (lst == NULL) {
         return FALSE;
     }
@@ -888,7 +904,17 @@ pcmk__str_in_list(GList *lst, const gchar *s)
         return TRUE;
     }
 
-    return g_list_find_custom(lst, s, (GCompareFunc) strcmp) != NULL;
+    if (s == NULL) {
+        return pcmk_is_set(flags, pcmk__str_null_matches);
+    }
+
+    if (pcmk_is_set(flags, pcmk__str_casei)) {
+        fn = (GCompareFunc) strcasecmp;
+    } else {
+        fn = (GCompareFunc) strcmp;
+    }
+
+    return g_list_find_custom(lst, s, fn) != NULL;
 }
 
 static bool
diff --git a/lib/fencing/st_output.c b/lib/fencing/st_output.c
index 568ae46a8..e1ae8ac87 100644
--- a/lib/fencing/st_output.c
+++ b/lib/fencing/st_output.c
@@ -47,7 +47,7 @@ stonith__failed_history(pcmk__output_t *out, va_list args) {
             continue;
         }
 
-        if (!pcmk__str_in_list(only_node, hp->target)) {
+        if (!pcmk__str_in_list(only_node, hp->target, pcmk__str_none)) {
             continue;
         }
 
@@ -72,7 +72,7 @@ stonith__history(pcmk__output_t *out, va_list args) {
     int rc = pcmk_rc_no_output;
 
     for (stonith_history_t *hp = history; hp; hp = hp->next) {
-        if (!pcmk__str_in_list(only_node, hp->target)) {
+        if (!pcmk__str_in_list(only_node, hp->target, pcmk__str_none)) {
             continue;
         }
 
@@ -101,7 +101,7 @@ stonith__full_history(pcmk__output_t *out, va_list args) {
     int rc = pcmk_rc_no_output;
 
     for (stonith_history_t *hp = history; hp; hp = hp->next) {
-        if (!pcmk__str_in_list(only_node, hp->target)) {
+        if (!pcmk__str_in_list(only_node, hp->target, pcmk__str_none)) {
             continue;
         }
 
@@ -129,7 +129,7 @@ full_history_xml(pcmk__output_t *out, va_list args) {
 
     if (history_rc == 0) {
         for (stonith_history_t *hp = history; hp; hp = hp->next) {
-            if (!pcmk__str_in_list(only_node, hp->target)) {
+            if (!pcmk__str_in_list(only_node, hp->target, pcmk__str_none)) {
                 continue;
             }
 
@@ -218,7 +218,7 @@ stonith__pending_actions(pcmk__output_t *out, va_list args) {
     int rc = pcmk_rc_no_output;
 
     for (stonith_history_t *hp = history; hp; hp = hp->next) {
-        if (!pcmk__str_in_list(only_node, hp->target)) {
+        if (!pcmk__str_in_list(only_node, hp->target, pcmk__str_none)) {
             continue;
         }
 
diff --git a/lib/pengine/bundle.c b/lib/pengine/bundle.c
index 9237392e4..6ba786ae6 100644
--- a/lib/pengine/bundle.c
+++ b/lib/pengine/bundle.c
@@ -1492,7 +1492,7 @@ pe__bundle_xml(pcmk__output_t *out, va_list args)
         return rc;
     }
 
-    print_everything = pcmk__str_in_list(only_rsc, rsc->id);
+    print_everything = pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none);
 
     for (GList *gIter = bundle_data->replicas; gIter != NULL;
          gIter = gIter->next) {
@@ -1614,7 +1614,7 @@ pe__bundle_html(pcmk__output_t *out, va_list args)
         return rc;
     }
 
-    print_everything = pcmk__str_in_list(only_rsc, rsc->id);
+    print_everything = pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none);
 
     for (GList *gIter = bundle_data->replicas; gIter != NULL;
          gIter = gIter->next) {
@@ -1742,7 +1742,7 @@ pe__bundle_text(pcmk__output_t *out, va_list args)
         return rc;
     }
 
-    print_everything = pcmk__str_in_list(only_rsc, rsc->id);
+    print_everything = pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none);
 
     for (GList *gIter = bundle_data->replicas; gIter != NULL;
          gIter = gIter->next) {
@@ -2044,7 +2044,7 @@ pe__bundle_is_filtered(pe_resource_t *rsc, GList *only_rsc, gboolean check_paren
     gboolean passes = FALSE;
     pe__bundle_variant_data_t *bundle_data = NULL;
 
-    if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc))) {
+    if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none)) {
         passes = TRUE;
     } else {
         get_bundle_variant_data(bundle_data, rsc);
diff --git a/lib/pengine/clone.c b/lib/pengine/clone.c
index 5662338f3..5a6bfa61f 100644
--- a/lib/pengine/clone.c
+++ b/lib/pengine/clone.c
@@ -624,8 +624,8 @@ pe__clone_xml(pcmk__output_t *out, va_list args)
         return rc;
     }
 
-    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
-                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
 
     for (; gIter != NULL; gIter = gIter->next) {
         pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
@@ -693,8 +693,8 @@ pe__clone_html(pcmk__output_t *out, va_list args)
         return rc;
     }
 
-    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
-                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
 
     out->begin_list(out, NULL, NULL, "Clone Set: %s [%s]%s%s%s%s",
                     rsc->id, ID(clone_data->xml_obj_child),
@@ -801,7 +801,7 @@ pe__clone_html(pcmk__output_t *out, va_list args)
     for (gIter = promoted_list; gIter; gIter = gIter->next) {
         pe_node_t *host = gIter->data;
 
-        if (!pcmk__str_in_list(only_node, host->details->uname)) {
+        if (!pcmk__str_in_list(only_node, host->details->uname, pcmk__str_none)) {
             continue;
         }
 
@@ -822,7 +822,7 @@ pe__clone_html(pcmk__output_t *out, va_list args)
     for (gIter = started_list; gIter; gIter = gIter->next) {
         pe_node_t *host = gIter->data;
 
-        if (!pcmk__str_in_list(only_node, host->details->uname)) {
+        if (!pcmk__str_in_list(only_node, host->details->uname, pcmk__str_none)) {
             continue;
         }
 
@@ -884,7 +884,7 @@ pe__clone_html(pcmk__output_t *out, va_list args)
                 pe_node_t *node = (pe_node_t *)nIter->data;
 
                 if (pe_find_node(rsc->running_on, node->details->uname) == NULL &&
-                    pcmk__str_in_list(only_node, node->details->uname)) {
+                    pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
                     pcmk__add_word(&stopped_list, &stopped_list_len,
                                    node->details->uname);
                 }
@@ -933,8 +933,8 @@ pe__clone_text(pcmk__output_t *out, va_list args)
         return rc;
     }
 
-    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
-                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
 
     out->begin_list(out, NULL, NULL, "Clone Set: %s [%s]%s%s%s%s",
                     rsc->id, ID(clone_data->xml_obj_child),
@@ -1041,7 +1041,7 @@ pe__clone_text(pcmk__output_t *out, va_list args)
     for (gIter = promoted_list; gIter; gIter = gIter->next) {
         pe_node_t *host = gIter->data;
 
-        if (!pcmk__str_in_list(only_node, host->details->uname)) {
+        if (!pcmk__str_in_list(only_node, host->details->uname, pcmk__str_none)) {
             continue;
         }
 
@@ -1062,7 +1062,7 @@ pe__clone_text(pcmk__output_t *out, va_list args)
     for (gIter = started_list; gIter; gIter = gIter->next) {
         pe_node_t *host = gIter->data;
 
-        if (!pcmk__str_in_list(only_node, host->details->uname)) {
+        if (!pcmk__str_in_list(only_node, host->details->uname, pcmk__str_none)) {
             continue;
         }
 
@@ -1120,7 +1120,7 @@ pe__clone_text(pcmk__output_t *out, va_list args)
                 pe_node_t *node = (pe_node_t *)nIter->data;
 
                 if (pe_find_node(rsc->running_on, node->details->uname) == NULL &&
-                    pcmk__str_in_list(only_node, node->details->uname)) {
+                    pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
                     pcmk__add_word(&stopped_list, &stopped_list_len,
                                    node->details->uname);
                 }
@@ -1220,11 +1220,11 @@ pe__clone_is_filtered(pe_resource_t *rsc, GList *only_rsc, gboolean check_parent
     gboolean passes = FALSE;
     clone_variant_data_t *clone_data = NULL;
 
-    if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc))) {
+    if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none)) {
         passes = TRUE;
     } else {
         get_clone_variant_data(clone_data, rsc);
-        passes = pcmk__str_in_list(only_rsc, ID(clone_data->xml_obj_child));
+        passes = pcmk__str_in_list(only_rsc, ID(clone_data->xml_obj_child), pcmk__str_none);
 
         if (!passes) {
             for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
diff --git a/lib/pengine/group.c b/lib/pengine/group.c
index 23a72cff7..5f9aa83ce 100644
--- a/lib/pengine/group.c
+++ b/lib/pengine/group.c
@@ -201,8 +201,8 @@ pe__group_xml(pcmk__output_t *out, va_list args)
         return rc;
     }
 
-    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
-                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
 
     for (; gIter != NULL; gIter = gIter->next) {
         pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
@@ -248,8 +248,8 @@ pe__group_html(pcmk__output_t *out, va_list args)
         return rc;
     }
 
-    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
-                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
 
     if (options & pe_print_brief) {
         GList *rscs = pe__filter_rsc_list(rsc->children, only_rsc);
@@ -303,8 +303,8 @@ pe__group_text(pcmk__output_t *out, va_list args)
         return rc;
     }
 
-    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
-                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+    print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+                       (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
 
     if (options & pe_print_brief) {
         GList *rscs = pe__filter_rsc_list(rsc->children, only_rsc);
@@ -387,11 +387,11 @@ pe__group_is_filtered(pe_resource_t *rsc, GList *only_rsc, gboolean check_parent
 {
     gboolean passes = FALSE;
 
-    if (check_parent && pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(rsc)))) {
+    if (check_parent && pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(rsc)), pcmk__str_none)) {
         passes = TRUE;
-    } else if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc))) {
+    } else if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none)) {
         passes = TRUE;
-    } else if (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id)) {
+    } else if (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none)) {
         passes = TRUE;
     } else {
         for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
diff --git a/lib/pengine/native.c b/lib/pengine/native.c
index c2333d0d2..56054fc4a 100644
--- a/lib/pengine/native.c
+++ b/lib/pengine/native.c
@@ -1338,8 +1338,8 @@ pe__rscs_brief_output(pcmk__output_t *out, GList *rsc_list, unsigned int show_op
 gboolean
 pe__native_is_filtered(pe_resource_t *rsc, GList *only_rsc, gboolean check_parent)
 {
-    if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
-        pcmk__str_in_list(only_rsc, rsc->id)) {
+    if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+        pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none)) {
         return FALSE;
     } else if (check_parent) {
         pe_resource_t *up = uber_parent(rsc);
diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c
index 727475735..a6dc4ade8 100644
--- a/lib/pengine/pe_output.c
+++ b/lib/pengine/pe_output.c
@@ -670,8 +670,8 @@ ban_list(pcmk__output_t *out, va_list args) {
             continue;
         }
 
-        if (!pcmk__str_in_list(only_rsc, rsc_printable_id(location->rsc_lh)) &&
-            !pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(location->rsc_lh)))) {
+        if (!pcmk__str_in_list(only_rsc, rsc_printable_id(location->rsc_lh), pcmk__str_none) &&
+            !pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(location->rsc_lh)), pcmk__str_none)) {
             continue;
         }
 
@@ -1254,7 +1254,7 @@ failed_action_list(pcmk__output_t *out, va_list args) {
          xml_op = pcmk__xml_next(xml_op)) {
         char *rsc = NULL;
 
-        if (!pcmk__str_in_list(only_node, crm_element_value(xml_op, XML_ATTR_UNAME))) {
+        if (!pcmk__str_in_list(only_node, crm_element_value(xml_op, XML_ATTR_UNAME), pcmk__str_none)) {
             continue;
         }
 
@@ -1263,7 +1263,7 @@ failed_action_list(pcmk__output_t *out, va_list args) {
             continue;
         }
 
-        if (!pcmk__str_in_list(only_rsc, rsc)) {
+        if (!pcmk__str_in_list(only_rsc, rsc, pcmk__str_none)) {
             free(rsc);
             continue;
         }
@@ -1738,7 +1738,7 @@ node_attribute_list(pcmk__output_t *out, va_list args) {
             continue;
         }
 
-        if (!pcmk__str_in_list(only_node, node->details->uname)) {
+        if (!pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
             g_list_free(attr_list);
             continue;
         }
@@ -1835,8 +1835,8 @@ node_history_list(pcmk__output_t *out, va_list args) {
          * For other resource types, is_filtered is okay.
          */
         if (uber_parent(rsc)->variant == pe_group) {
-            if (!pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) &&
-                !pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(rsc)))) {
+            if (!pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) &&
+                !pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(rsc)), pcmk__str_none)) {
                 continue;
             }
         } else {
@@ -1899,7 +1899,7 @@ node_list_html(pcmk__output_t *out, va_list args) {
     for (GList *gIter = nodes; gIter != NULL; gIter = gIter->next) {
         pe_node_t *node = (pe_node_t *) gIter->data;
 
-        if (!pcmk__str_in_list(only_node, node->details->uname)) {
+        if (!pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
             continue;
         }
 
@@ -1940,7 +1940,7 @@ pe__node_list_text(pcmk__output_t *out, va_list args) {
         const char *node_mode = NULL;
         char *node_name = pe__node_display_name(node, print_clone_detail);
 
-        if (!pcmk__str_in_list(only_node, node->details->uname)) {
+        if (!pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
             free(node_name);
             continue;
         }
@@ -2059,7 +2059,7 @@ node_list_xml(pcmk__output_t *out, va_list args) {
     for (GList *gIter = nodes; gIter != NULL; gIter = gIter->next) {
         pe_node_t *node = (pe_node_t *) gIter->data;
 
-        if (!pcmk__str_in_list(only_node, node->details->uname)) {
+        if (!pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
             continue;
         }
 
@@ -2097,7 +2097,7 @@ node_summary(pcmk__output_t *out, va_list args) {
             continue;
         }
 
-        if (!pcmk__str_in_list(only_node, node->details->uname)) {
+        if (!pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
             continue;
         }
 
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
index 450d8348c..d1be9e4ca 100644
--- a/lib/pengine/utils.c
+++ b/lib/pengine/utils.c
@@ -2394,7 +2394,7 @@ pe__rsc_running_on_any_node_in_list(pe_resource_t *rsc, GList *node_list)
 {
     for (GList *ele = rsc->running_on; ele; ele = ele->next) {
         pe_node_t *node = (pe_node_t *) ele->data;
-        if (pcmk__str_in_list(node_list, node->details->uname)) {
+        if (pcmk__str_in_list(node_list, node->details->uname, pcmk__str_none)) {
             return true;
         }
     }
@@ -2419,8 +2419,8 @@ pe__filter_rsc_list(GList *rscs, GList *filter)
         /* I think the second condition is safe here for all callers of this
          * function.  If not, it needs to move into pe__node_text.
          */
-        if (pcmk__str_in_list(filter, rsc_printable_id(rsc)) ||
-            (rsc->parent && pcmk__str_in_list(filter, rsc_printable_id(rsc->parent)))) {
+        if (pcmk__str_in_list(filter, rsc_printable_id(rsc), pcmk__str_none) ||
+            (rsc->parent && pcmk__str_in_list(filter, rsc_printable_id(rsc->parent), pcmk__str_none))) {
             retval = g_list_prepend(retval, rsc);
         }
     }
-- 
2.27.0