diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e1702dbff3..4c1f61cefc 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1908,6 +1908,7 @@ virStringSearch; virStringSortCompare; virStringSortRevCompare; virStringSplit; +virStringSplitCount; virStrncpy; virStrndup; virStrToDouble; diff --git a/src/util/virstring.c b/src/util/virstring.c index 7a8430e847..6dcc7a8acc 100644 --- a/src/util/virstring.c +++ b/src/util/virstring.c @@ -43,13 +43,15 @@ VIR_LOG_INIT("util.string"); */ /** - * virStringSplit: + * virStringSplitCount: * @string: a string to split * @delim: a string which specifies the places at which to split * the string. The delimiter is not included in any of the resulting * strings, unless @max_tokens is reached. * @max_tokens: the maximum number of pieces to split @string into. * If this is 0, the string is split completely. + * @tokcount: If provided, the value is set to the count of pieces the string + * was split to excluding the terminating NULL element. * * Splits a string into a maximum of @max_tokens pieces, using the given * @delim. If @max_tokens is reached, the remainder of @string is @@ -65,9 +67,11 @@ VIR_LOG_INIT("util.string"); * Return value: a newly-allocated NULL-terminated array of strings. Use * virStringFreeList() to free it. */ -char **virStringSplit(const char *string, - const char *delim, - size_t max_tokens) +char ** +virStringSplitCount(const char *string, + const char *delim, + size_t max_tokens, + size_t *tokcount) { char **tokens = NULL; size_t ntokens = 0; @@ -109,6 +113,9 @@ char **virStringSplit(const char *string, goto error; tokens[ntokens++] = NULL; + if (tokcount) + *tokcount = ntokens - 1; + return tokens; error: @@ -119,6 +126,15 @@ char **virStringSplit(const char *string, } +char ** +virStringSplit(const char *string, + const char *delim, + size_t max_tokens) +{ + return virStringSplitCount(string, delim, max_tokens, NULL); +} + + /** * virStringJoin: * @strings: a NULL-terminated array of strings to join diff --git a/src/util/virstring.h b/src/util/virstring.h index 1ed104682c..0ab9d9633f 100644 --- a/src/util/virstring.h +++ b/src/util/virstring.h @@ -26,6 +26,12 @@ # include "internal.h" +char **virStringSplitCount(const char *string, + const char *delim, + size_t max_tokens, + size_t *tokcount) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + char **virStringSplit(const char *string, const char *delim, size_t max_tokens) diff --git a/tests/virstringtest.c b/tests/virstringtest.c index 96c3784a58..5277fc657a 100644 --- a/tests/virstringtest.c +++ b/tests/virstringtest.c @@ -53,11 +53,14 @@ static int testSplit(const void *args) { const struct testSplitData *data = args; char **got; + size_t ntokens; + size_t exptokens = 0; char **tmp1; const char **tmp2; int ret = -1; - if (!(got = virStringSplit(data->string, data->delim, data->max_tokens))) { + if (!(got = virStringSplitCount(data->string, data->delim, + data->max_tokens, &ntokens))) { VIR_DEBUG("Got no tokens at all"); return -1; } @@ -71,6 +74,7 @@ static int testSplit(const void *args) } tmp1++; tmp2++; + exptokens++; } if (*tmp1) { virFilePrintf(stderr, "Too many pieces returned\n"); @@ -81,6 +85,14 @@ static int testSplit(const void *args) goto cleanup; } + if (ntokens != exptokens) { + virFilePrintf(stderr, + "Returned token count (%zu) doesn't match " + "expected count (%zu)", + ntokens, exptokens); + goto cleanup; + } + ret = 0; cleanup: virStringFreeList(got);