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