Blob Blame History Raw
From 7cadfbf00aed1ba88bf593b02ee5946ba5f54bde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 28 Nov 2018 13:45:33 +0100
Subject: [PATCH 1/3] util: remove duplicate values correctly in
 string_array_del_value

---
 src/lib/util/string_array.c        |  27 ++++--
 src/tests/test_util_string_array.c | 146 ++++++++++++++++++++++++++++-
 2 files changed, 163 insertions(+), 10 deletions(-)

diff --git a/src/lib/util/string_array.c b/src/lib/util/string_array.c
index e56d66bdcce7c8a1cf99f9b91068614c4b8d3d81..a8afa5ab8edbb26d6f946619f9ce0b83c511bb8c 100644
--- a/src/lib/util/string_array.c
+++ b/src/lib/util/string_array.c
@@ -140,24 +140,33 @@ string_array_add_value(char **array, const char *value, bool unique)
 char **
 string_array_del_value(char **array, const char *value)
 {
-    bool found = false;
-    int i;
+    size_t count;
+    size_t pos;
+    size_t i;

-    if (!string_array_has_value(array, value)) {
-        return array;
+    if (array == NULL) {
+        return NULL;
     }

-    for (i = 0; array[i] != NULL; i++) {
-        if (strcmp(value, array[i]) == 0) {
+    count = string_array_count(array);
+    for (i = 0; i < count; i++) {
+        if (strcmp(array[i], value) == 0) {
             free(array[i]);
-            found = true;
+            array[i] = NULL;
         }
+    }

-        if (found) {
-            array[i] = array[i + 1];
+    for (i = 0, pos = 0; i < count; i++) {
+        if (array[i] != NULL) {
+            array[pos] = array[i];
+            pos++;
         }
     }

+    for (; pos < count; pos++) {
+        array[pos] = NULL;
+    }
+
     return array;
 }

diff --git a/src/tests/test_util_string_array.c b/src/tests/test_util_string_array.c
index 4f6812e9396f04bbbfb72bda8a9022501f074faf..249cb96acea3c4feac910702572cafb1025d9496 100644
--- a/src/tests/test_util_string_array.c
+++ b/src/tests/test_util_string_array.c
@@ -32,11 +32,155 @@ void test_string_array_create(void **state)
     string_array_free(array);
 }

+void test_string_array_del_value__single(void **state)
+{
+    char **array;
+    const char *values[] = {"1", "2", "3", "4", "5", NULL};
+    const char *expected[] = {"1", "3", "4", "5", NULL};
+    int i;
+
+    array = string_array_create(10);
+    assert_non_null(array);
+
+    /* Fill array. */
+    for (i = 0; values[i] != NULL; i++) {
+        array = string_array_add_value(array, values[i], false);
+        assert_non_null(array);
+        assert_non_null(array[i]);
+    }
+    assert_null(array[i]);
+
+    /* Delete value. */
+    array = string_array_del_value(array, "2");
+    assert_non_null(array);
+
+    /* Test values. */
+    for (i = 0; expected[i] != NULL; i++) {
+        assert_non_null(array[i]);
+        assert_string_equal(array[i], expected[i]);
+    }
+    assert_null(array[i]);
+
+    string_array_free(array);
+}
+
+void test_string_array_del_value__single_repeated(void **state)
+{
+    char **array;
+    const char *values[] = {"1", "2", "2", "3", "2", "4", "2", "5", NULL};
+    const char *expected[] = {"1", "3", "4", "5", NULL};
+    int i;
+
+    array = string_array_create(10);
+    assert_non_null(array);
+
+    /* Fill array. */
+    for (i = 0; values[i] != NULL; i++) {
+        array = string_array_add_value(array, values[i], false);
+        assert_non_null(array);
+        assert_non_null(array[i]);
+    }
+    assert_null(array[i]);
+
+    /* Delete value. */
+    array = string_array_del_value(array, "2");
+    assert_non_null(array);
+
+    /* Test values. */
+    for (i = 0; expected[i] != NULL; i++) {
+        assert_non_null(array[i]);
+        assert_string_equal(array[i], expected[i]);
+    }
+    assert_null(array[i]);
+
+    string_array_free(array);
+}
+
+void test_string_array_del_value__multiple(void **state)
+{
+    char **array;
+    const char *values[] = {"1", "2", "3", "4", "5", NULL};
+    const char *expected[] = {"1", "4", NULL};
+    int i;
+
+    array = string_array_create(10);
+    assert_non_null(array);
+
+    /* Fill array. */
+    for (i = 0; values[i] != NULL; i++) {
+        array = string_array_add_value(array, values[i], false);
+        assert_non_null(array);
+        assert_non_null(array[i]);
+    }
+    assert_null(array[i]);
+
+    /* Delete value. */
+    array = string_array_del_value(array, "2");
+    assert_non_null(array);
+
+    array = string_array_del_value(array, "3");
+    assert_non_null(array);
+
+    array = string_array_del_value(array, "5");
+    assert_non_null(array);
+
+    /* Test values. */
+    for (i = 0; expected[i] != NULL; i++) {
+        assert_non_null(array[i]);
+        assert_string_equal(array[i], expected[i]);
+    }
+    assert_null(array[i]);
+
+    string_array_free(array);
+}
+
+void test_string_array_del_value__multiple_repeated(void **state)
+{
+    char **array;
+    const char *values[] = {"1", "2", "2", "3", "3", "2", "4", "2", "5", "5", NULL};
+    const char *expected[] = {"1", "4", NULL};
+    int i;
+
+    array = string_array_create(10);
+    assert_non_null(array);
+
+    /* Fill array. */
+    for (i = 0; values[i] != NULL; i++) {
+        array = string_array_add_value(array, values[i], false);
+        assert_non_null(array);
+        assert_non_null(array[i]);
+    }
+    assert_null(array[i]);
+
+    /* Delete value. */
+    array = string_array_del_value(array, "2");
+    assert_non_null(array);
+
+    array = string_array_del_value(array, "3");
+    assert_non_null(array);
+
+    array = string_array_del_value(array, "5");
+    assert_non_null(array);
+
+    /* Test values. */
+    for (i = 0; expected[i] != NULL; i++) {
+        assert_non_null(array[i]);
+        assert_string_equal(array[i], expected[i]);
+    }
+    assert_null(array[i]);
+
+    string_array_free(array);
+}
+
 int main(int argc, const char *argv[])
 {

     const struct CMUnitTest tests[] = {
-        cmocka_unit_test(test_string_array_create)
+        cmocka_unit_test(test_string_array_create),
+        cmocka_unit_test(test_string_array_del_value__single),
+        cmocka_unit_test(test_string_array_del_value__single_repeated),
+        cmocka_unit_test(test_string_array_del_value__multiple),
+        cmocka_unit_test(test_string_array_del_value__multiple_repeated)
     };

     return cmocka_run_group_tests(tests, NULL, NULL);
--
2.17.2