[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