[libvirt] [PATCH 2/2] Add virStringReplace method for substring replacement
Ján Tomko
jtomko at redhat.com
Thu Feb 20 10:52:25 UTC 2014
On 02/19/2014 09:36 PM, Daniel P. Berrange wrote:
> Add a virStringReplace method to virstring.{h,c} to perform
> substring matching and replacement
>
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
> src/libvirt_private.syms | 1 +
> src/util/virstring.c | 44 +++++++++++++++++++++++++++++++++++-
> src/util/virstring.h | 5 ++++
> tests/virstringtest.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 108 insertions(+), 1 deletion(-)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index f26190d..f7379a2 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1794,6 +1794,7 @@ virStringArrayHasString;
> virStringFreeList;
> virStringJoin;
> virStringListLength;
> +virStringReplace;
> virStringSearch;
> virStringSortCompare;
> virStringSortRevCompare;
> diff --git a/src/util/virstring.c b/src/util/virstring.c
> index 67a87d3..3e42b06 100644
> --- a/src/util/virstring.c
> +++ b/src/util/virstring.c
> @@ -619,7 +619,6 @@ size_t virStringListLength(char **strings)
> return i;
> }
>
> -
> /**
> * virStringSortCompare:
> *
Unrelated whitespace change.
> @@ -747,3 +746,46 @@ cleanup:
> }
> return ret;
> }
> +
> +/**
> + * virStringReplace:
> + * @haystack: the source string to process
> + * @oldneedle: the substring to locate
> + * @newneedle: the substring to insert
> + *
> + * Search @haystack and replace all occurences of @oldneedle with @newneedle.
> + *
> + * Returns: a new string with all the replacements, or NULL on error
> + */
> +char *
> +virStringReplace(const char *haystack,
> + const char *oldneedle,
> + const char *newneedle)
> +{
> + virBuffer buf = VIR_BUFFER_INITIALIZER;
> + const char *tmp1, *tmp2;
> + size_t oldneedlelen = strlen(oldneedle);
> + size_t newneedlelen = strlen(newneedle);
> +
> + tmp1 = haystack;
> + tmp2 = NULL;
> +
> + while (tmp1) {
> + tmp2 = strstr(tmp1, oldneedle);
> +
> + if (tmp2) {
> + virBufferAdd(&buf, tmp1, (tmp2 - tmp1));
> + virBufferAdd(&buf, newneedle, newneedlelen);
> + tmp2 += oldneedlelen;
> + } else {
> + virBufferAdd(&buf, tmp1, -1);
> + }
> +
> + tmp1 = tmp2;
> + }
> +
> + if (virBufferError(&buf))
virBufferError doesn't report an error, but I think this function should.
> + return NULL;
> +
> + return virBufferContentAndReset(&buf);
> +}
> diff --git a/tests/virstringtest.c b/tests/virstringtest.c
> index b8c6115..43023d5 100644
> --- a/tests/virstringtest.c
> +++ b/tests/virstringtest.c
> @@ -428,6 +460,33 @@ mymain(void)
> const char *matches3[] = { "foo", "bar" };
> TEST_SEARCH("1foo2bar3eek", "([a-z]+)", 2, 2, matches3, false);
>
> +#define TEST_REPLACE(h, o, n, r) \
> + do { \
> + struct stringReplaceData data = { \
> + .haystack = h, \
> + .oldneedle = o, \
> + .newneedle = n, \
> + .result = r \
> + }; \
> + if (virtTestRun("virStringReplace " h, testStringReplace, &data) < 0) \
> + ret = -1; \
> + } while (0)
> +
> + /* no matches */
> + TEST_REPLACE("foo", "bar", "eek", "foo");
> +
> + /* complete match */
> + TEST_REPLACE("foo", "foo", "bar", "bar");
> +
> + /* middle match */
> + TEST_REPLACE("foobarwizz", "bar", "eek", "fooeekwizz");
> +
> + /* many matches */
> + TEST_REPLACE("foofoofoofoo", "foo", "bar", "barbarbarbar");
> +
> + /* many matches */
> + TEST_REPLACE("fooooofoooo", "foo", "bar", "barooobaroo");
> +
> return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
> }
>
A test with different length of old and new needles would be nice.
ACK with error reporting.
Jan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20140220/8aa591de/attachment-0001.sig>
More information about the libvir-list
mailing list