289 lines
8.3 KiB
Diff
289 lines
8.3 KiB
Diff
|
From 4208646609da9b25b70c21f5f39c92fabbd59dfc Mon Sep 17 00:00:00 2001
|
||
|
From: Sumit Bose <sbose@redhat.com>
|
||
|
Date: Thu, 14 Jun 2018 16:48:22 +0200
|
||
|
Subject: [PATCH 21/23] 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
|
||
|
|