From 3c97263990648f808010220a080f4f9a4e846dac Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 14 Jun 2018 16:48:22 +0200
Subject: [PATCH 6/7] util: add _adcli_strv_remove_unsorted
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1547014
---
library/adprivate.h | 4 ++
library/adutil.c | 21 ++++++++
library/seq.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++---
library/seq.h | 12 +++++
4 files changed, 179 insertions(+), 7 deletions(-)
diff --git a/library/adprivate.h b/library/adprivate.h
index 7485249..bc9df6d 100644
--- a/library/adprivate.h
+++ b/library/adprivate.h
@@ -111,6 +111,10 @@ char ** _adcli_strv_add (char **strv,
char *string,
int *length) GNUC_WARN_UNUSED;
+void _adcli_strv_remove_unsorted (char **strv,
+ const char *string,
+ int *length);
+
void _adcli_strv_free (char **strv);
int _adcli_strv_has (char **strv,
diff --git a/library/adutil.c b/library/adutil.c
index a27bd68..6334b52 100644
--- a/library/adutil.c
+++ b/library/adutil.c
@@ -221,6 +221,27 @@ _adcli_strv_add (char **strv,
return seq_push (strv, length, string);
}
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
+
+void
+_adcli_strv_remove_unsorted (char **strv,
+ const char *string,
+ int *length)
+{
+ int len;
+
+ return_if_fail (string != NULL);
+
+ if (!length) {
+ len = seq_count (strv);
+ length = &len;
+ }
+
+ return seq_remove_unsorted (strv, length, discard_const (string),
+ (seq_compar)strcasecmp, free);
+}
+
+
int
_adcli_strv_has (char **strv,
const char *str)
diff --git a/library/seq.c b/library/seq.c
index 627dcaf..8e7475d 100644
--- a/library/seq.c
+++ b/library/seq.c
@@ -111,6 +111,24 @@ seq_push (seq_voidp sequence,
return seq;
}
+static int
+linear_search (void **seq,
+ int low,
+ int high,
+ void *match,
+ seq_compar compar)
+{
+ int at;
+
+ for (at = low; at < high; at++) {
+ if (compar (match, seq[at]) == 0) {
+ break;
+ }
+ }
+
+ return at;
+}
+
static int
binary_search (void **seq,
int low,
@@ -171,12 +189,13 @@ seq_insert (seq_voidp sequence,
return seq;
}
-void
-seq_remove (seq_voidp sequence,
- int *length,
- void *match,
- seq_compar compar,
- seq_destroy destroy)
+static void
+seq_remove_int (seq_voidp sequence,
+ int *length,
+ void *match,
+ seq_search search,
+ seq_compar compar,
+ seq_destroy destroy)
{
void **seq = sequence;
int at;
@@ -187,7 +206,7 @@ seq_remove (seq_voidp sequence,
assert (match != NULL);
len = *length;
- at = binary_search (seq, 0, len, match, compar);
+ at = search (seq, 0, len, match, compar);
/* We have a matching value */
if (at < len && compar (match, seq[at]) == 0) {
@@ -201,6 +220,26 @@ seq_remove (seq_voidp sequence,
*length = len;
}
+void
+seq_remove (seq_voidp sequence,
+ int *length,
+ void *match,
+ seq_compar compar,
+ seq_destroy destroy)
+{
+ return seq_remove_int (sequence, length, match, binary_search, compar, destroy);
+}
+
+void
+seq_remove_unsorted (seq_voidp sequence,
+ int *length,
+ void *match,
+ seq_compar compar,
+ seq_destroy destroy)
+{
+ return seq_remove_int (sequence, length, match, linear_search, compar, destroy);
+}
+
void
seq_filter (seq_voidp sequence,
int *length,
@@ -430,6 +469,99 @@ test_remove (void)
seq_free (seq, NULL);
}
+static void
+test_remove_unsorted (void)
+{
+ void **seq = NULL;
+ int len = 0;
+
+ seq = seq_push (seq, &len, "3");
+ seq = seq_push (seq, &len, "5");
+ seq = seq_push (seq, &len, "1");
+ seq = seq_push (seq, &len, "4");
+ seq = seq_push (seq, &len, "2");
+
+ assert_str_eq (seq[0], "3");
+ assert_str_eq (seq[1], "5");
+ assert_str_eq (seq[2], "1");
+ assert_str_eq (seq[3], "4");
+ assert_str_eq (seq[4], "2");
+ assert (seq[5] == NULL);
+ assert_num_eq (len, 5);
+
+ seq_remove_unsorted (seq, &len, "3", (seq_compar)strcmp, NULL);
+ seq_remove_unsorted (seq, &len, "2", (seq_compar)strcmp, NULL);
+
+ assert_str_eq (seq[0], "5");
+ assert_str_eq (seq[1], "1");
+ assert_str_eq (seq[2], "4");
+ assert (seq[3] == NULL);
+ assert_num_eq (len, 3);
+
+ seq_free (seq, NULL);
+}
+
+static void
+test_remove_first (void)
+{
+ void **seq = NULL;
+ int len = 0;
+
+ seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "5", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
+
+ assert_str_eq (seq[0], "1");
+ assert_str_eq (seq[1], "2");
+ assert_str_eq (seq[2], "3");
+ assert_str_eq (seq[3], "4");
+ assert_str_eq (seq[4], "5");
+ assert (seq[5] == NULL);
+ assert_num_eq (len, 5);
+
+ seq_remove (seq, &len, "1", (seq_compar)strcmp, NULL);
+
+ assert_str_eq (seq[0], "2");
+ assert_str_eq (seq[1], "3");
+ assert_str_eq (seq[2], "4");
+ assert_str_eq (seq[3], "5");
+ assert (seq[4] == NULL);
+ assert_num_eq (len, 4);
+
+ seq_free (seq, NULL);
+}
+
+static void
+test_remove_last (void)
+{
+ void **seq = NULL;
+ int len = 0;
+
+ seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
+ seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
+
+ assert_str_eq (seq[0], "1");
+ assert_str_eq (seq[1], "2");
+ assert_str_eq (seq[2], "3");
+ assert_str_eq (seq[3], "4");
+ assert (seq[4] == NULL);
+ assert_num_eq (len, 4);
+
+ seq_remove (seq, &len, "4", (seq_compar)strcmp, NULL);
+
+ assert_str_eq (seq[0], "1");
+ assert_str_eq (seq[1], "2");
+ assert_str_eq (seq[2], "3");
+ assert (seq[3] == NULL);
+ assert_num_eq (len, 3);
+
+ seq_free (seq, NULL);
+}
+
static int
compar_even (void *match,
void *value)
@@ -631,6 +763,9 @@ main (int argc,
test_func (test_insert, "/seq/insert");
test_func (test_insert_destroys, "/seq/insert_destroys");
test_func (test_remove, "/seq/remove");
+ test_func (test_remove_unsorted, "/seq/remove_unsorted");
+ test_func (test_remove_first, "/seq/remove_first");
+ test_func (test_remove_last, "/seq/remove_last");
test_func (test_remove_destroys, "/seq/remove_destroys");
test_func (test_filter, "/seq/filter");
test_func (test_filter_null, "/seq/filter_null");
diff --git a/library/seq.h b/library/seq.h
index 694965b..5d48848 100644
--- a/library/seq.h
+++ b/library/seq.h
@@ -44,6 +44,12 @@ typedef void * (* seq_copy) (void *value);
typedef void (* seq_destroy) (void *value);
+typedef int (* seq_search) (void **seq,
+ int low,
+ int high,
+ void *match,
+ seq_compar compar);
+
seq_voidp seq_push (seq_voidp seq,
int *length,
void *value) WARN_UNUSED;
@@ -62,6 +68,12 @@ void seq_remove (seq_voidp seq,
seq_compar compar,
seq_destroy destroy);
+void seq_remove_unsorted (seq_voidp seq,
+ int *length,
+ void *match,
+ seq_compar compar,
+ seq_destroy destroy);
+
seq_voidp seq_lookup (seq_voidp seq,
int *length,
void *match,
--
2.14.4