Signed-off-by: Michal Privoznik <mpriv...@redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virstring.c     | 50 ++++++++++++++++++++++++++++++++++++++++++
 src/util/virstring.h     |  3 +++
 tests/virstringtest.c    | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 110 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index bc6588969..3d4da7356 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2467,6 +2467,7 @@ virStringListGetFirstWithPrefix;
 virStringListHasString;
 virStringListJoin;
 virStringListLength;
+virStringListRemove;
 virStringReplace;
 virStringSearch;
 virStringSortCompare;
diff --git a/src/util/virstring.c b/src/util/virstring.c
index 629f8ca32..96786db7f 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -202,6 +202,56 @@ virStringListAdd(const char **strings,
 }
 
 
+/**
+ * virStringListRemove:
+ * @strings: a NULL-terminated array of strings
+ * @newStrings: new NULL-terminated array of strings
+ * @item: string to remove
+ *
+ * Creates new strings list with all strings duplicated except
+ * for every occurrence of @item. Callers is responsible for
+ * freeing both @strings and returned list.
+ *
+ * Returns the number of items in the new list (excluding NULL
+ * anchor), -1 on error.
+ */
+int
+virStringListRemove(const char **strings,
+                    char ***newStrings,
+                    const char *item)
+{
+    char **ret = NULL;
+    size_t i, j = 0;
+
+    for (i = 0; strings && strings[i]; i++) {
+        if (STRNEQ(strings[i], item))
+            j++;
+    }
+
+    if (!j) {
+        *newStrings = NULL;
+        return 0;
+    }
+
+    if (VIR_ALLOC_N(ret, j + 1) < 0)
+        goto error;
+
+    for (i = 0, j = 0; strings[i]; i++) {
+        if (STREQ(strings[i], item))
+            continue;
+        if (VIR_STRDUP(ret[j], strings[i]) < 0)
+            goto error;
+        j++;
+    }
+
+    *newStrings = ret;
+    return j;
+ error:
+    virStringListFree(ret);
+    return -1;
+}
+
+
 /**
  * virStringListFree:
  * @str_array: a NULL-terminated array of strings to free
diff --git a/src/util/virstring.h b/src/util/virstring.h
index da9d35cca..88eacd404 100644
--- a/src/util/virstring.h
+++ b/src/util/virstring.h
@@ -43,6 +43,9 @@ char *virStringListJoin(const char **strings,
 
 char **virStringListAdd(const char **strings,
                         const char *item);
+int virStringListRemove(const char **strings,
+                        char ***newStrings,
+                        const char *item);
 
 void virStringListFree(char **strings);
 void virStringListFreeCount(char **strings,
diff --git a/tests/virstringtest.c b/tests/virstringtest.c
index 43657c84c..63a5e90db 100644
--- a/tests/virstringtest.c
+++ b/tests/virstringtest.c
@@ -162,6 +162,60 @@ static int testAdd(const void *args)
 }
 
 
+static int testRemove(const void *args)
+{
+    const struct testSplitData *data = args;
+    char **list = NULL;
+    size_t ntokens;
+    size_t i;
+    int ret = -1;
+    size_t listLenght;
+
+    if (!(list = virStringSplitCount(data->string, data->delim,
+                                     data->max_tokens, &ntokens))) {
+        VIR_DEBUG("Got no tokens at all");
+        return -1;
+    }
+
+    listLenght = virStringListLength((const char **) list);
+
+    for (i = 0; data->tokens[i]; i++) {
+        char **tmp;
+        int rv;
+        size_t j, toRemove = 0;
+
+        for (j = 0; list && list[j]; j++)
+            if (STREQ(list[j], data->tokens[i]))
+                toRemove++;
+
+        if ((rv = virStringListRemove((const char **) list,
+                                      &tmp, data->tokens[i])) < 0)
+            goto cleanup;
+        virStringListFree(list);
+        list = tmp;
+        tmp = NULL;
+        listLenght -= toRemove;
+
+        if (rv != listLenght) {
+            virFilePrintf(stderr,
+                          "Unexpected length of new list: %d expected %zu",
+                          rv, listLenght);
+            goto cleanup;
+        }
+    }
+
+    if (list && list[0]) {
+        virFilePrintf(stderr, "Not removed all tokens: %s", list[0]);
+        goto cleanup;
+    }
+
+    ret = 0;
+ cleanup:
+    virStringListFree(list);
+    return ret;
+}
+
+
 static bool fail;
 
 static const char *
@@ -636,6 +690,8 @@ mymain(void)
             ret = -1;                                                   \
         if (virTestRun("Add " #str, testAdd, &joinData) < 0)            \
             ret = -1;                                                   \
+        if (virTestRun("Remove " #str, testRemove, &splitData) < 0)     \
+            ret = -1;                                                   \
     } while (0)
 
     const char *tokens1[] = { NULL };
-- 
2.11.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to