diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 43220e0656..bc6588969a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2460,6 +2460,7 @@ virStringEncodeBase64; virStringHasControlChars; virStringIsEmpty; virStringIsPrintable; +virStringListAdd; virStringListFree; virStringListFreeCount; virStringListGetFirstWithPrefix; diff --git a/src/util/virstring.c b/src/util/virstring.c index 740cf4d238..629f8ca32e 100644 --- a/src/util/virstring.c +++ b/src/util/virstring.c @@ -168,6 +168,40 @@ char *virStringListJoin(const char **strings, } +/** + * virStringListAdd: + * @strings: a NULL-terminated array of strings + * @item: string to add + * + * Creates new strings list with all strings duplicated and @item + * at the end of the list. Callers is responsible for freeing + * both @strings and returned list. + */ +char ** +virStringListAdd(const char **strings, + const char *item) +{ + char **ret = NULL; + size_t i = virStringListLength(strings); + + if (VIR_ALLOC_N(ret, i + 2) < 0) + goto error; + + for (i = 0; strings && strings[i]; i++) { + if (VIR_STRDUP(ret[i], strings[i]) < 0) + goto error; + } + + if (VIR_STRDUP(ret[i], item) < 0) + goto error; + + return ret; + error: + virStringListFree(ret); + return NULL; +} + + /** * virStringListFree: * @str_array: a NULL-terminated array of strings to free diff --git a/src/util/virstring.h b/src/util/virstring.h index f6801fcd14..da9d35ccad 100644 --- a/src/util/virstring.h +++ b/src/util/virstring.h @@ -41,6 +41,9 @@ char *virStringListJoin(const char **strings, const char *delim) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +char **virStringListAdd(const char **strings, + const char *item); + void virStringListFree(char **strings); void virStringListFreeCount(char **strings, size_t count); diff --git a/tests/virstringtest.c b/tests/virstringtest.c index a11d7c5d87..43657c84c5 100644 --- a/tests/virstringtest.c +++ b/tests/virstringtest.c @@ -122,6 +122,46 @@ static int testJoin(const void *args) return ret; } + +static int testAdd(const void *args) +{ + const struct testJoinData *data = args; + char **list = NULL; + char *got = NULL; + int ret = -1; + size_t i; + + for (i = 0; data->tokens[i]; i++) { + char **tmp = virStringListAdd((const char **)list, data->tokens[i]); + if (!tmp) + goto cleanup; + virStringListFree(list); + list = tmp; + tmp = NULL; + } + + if (!list && + VIR_ALLOC(list) < 0) + goto cleanup; + + if (!(got = virStringListJoin((const char **)list, data->delim))) { + VIR_DEBUG("Got no result"); + goto cleanup; + } + + if (STRNEQ(got, data->string)) { + virFilePrintf(stderr, "Mismatch '%s' vs '%s'\n", got, data->string); + goto cleanup; + } + + ret = 0; + cleanup: + virStringListFree(list); + VIR_FREE(got); + return ret; +} + + static bool fail; static const char * @@ -594,6 +634,8 @@ mymain(void) ret = -1; \ if (virTestRun("Join " #str, testJoin, &joinData) < 0) \ ret = -1; \ + if (virTestRun("Add " #str, testAdd, &joinData) < 0) \ + ret = -1; \ } while (0) const char *tokens1[] = { NULL };