From b379c44c3506dda1c23a4de930c0c9509cb8c3a6 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Mon, 28 Nov 2016 14:38:58 +0100 Subject: [PATCH] virstring: Introduce virStringListRemove Signed-off-by: Michal Privoznik --- src/libvirt_private.syms | 1 + src/util/virstring.c | 35 +++++++++++++++++++++++++++++++++++ src/util/virstring.h | 2 ++ tests/virstringtest.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index bc6588969a..3d4da73562 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 629f8ca32e..69abc267bf 100644 --- a/src/util/virstring.c +++ b/src/util/virstring.c @@ -202,6 +202,41 @@ virStringListAdd(const char **strings, } +/** + * virStringListRemove: + * @strings: a NULL-terminated array of strings + * @item: string to remove + * + * Remove every occurrence of @item in list of @strings. + */ +void +virStringListRemove(char ***strings, + const char *item) +{ + size_t r, w = 0; + + if (!strings || !*strings) + return; + + for (r = 0; (*strings)[r]; r++) { + if (STREQ((*strings)[r], item)) { + VIR_FREE((*strings)[r]); + continue; + } + if (r != w) + (*strings)[w] = (*strings)[r]; + w++; + } + + if (w == 0) { + VIR_FREE(*strings); + } else { + (*strings)[w] = NULL; + ignore_value(VIR_REALLOC_N(*strings, w + 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 da9d35ccad..a5550e30d2 100644 --- a/src/util/virstring.h +++ b/src/util/virstring.h @@ -43,6 +43,8 @@ char *virStringListJoin(const char **strings, char **virStringListAdd(const char **strings, const char *item); +void virStringListRemove(char ***strings, + const char *item); void virStringListFree(char **strings); void virStringListFreeCount(char **strings, diff --git a/tests/virstringtest.c b/tests/virstringtest.c index 43657c84c5..1d660b7984 100644 --- a/tests/virstringtest.c +++ b/tests/virstringtest.c @@ -162,6 +162,40 @@ 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; + + if (!(list = virStringSplitCount(data->string, data->delim, + data->max_tokens, &ntokens))) { + VIR_DEBUG("Got no tokens at all"); + return -1; + } + + for (i = 0; data->tokens[i]; i++) { + virStringListRemove(&list, data->tokens[i]); + if (virStringListHasString((const char **) list, data->tokens[i])) { + virFilePrintf(stderr, "Not removed %s", data->tokens[i]); + 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 +670,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 };