[libvirt] [PATCH 1/2] util: introduce virStringMatch

John Ferlan jferlan at redhat.com
Fri May 12 10:44:16 UTC 2017



On 05/11/2017 11:49 AM, Pavel Hrdina wrote:
> Simply tries to match the provided regex on a string and returns
> the result.  Useful if caller don't care about the matched substring
> and want to just test if some pattern patches a string.
> 
> Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
> ---
>  src/libvirt_private.syms |  1 +
>  src/util/virstring.c     | 34 ++++++++++++++++++++++++++++++++++
>  src/util/virstring.h     |  3 +++
>  tests/virstringtest.c    | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 85 insertions(+)
> 

Something to consider seeing as this function could be "reused" if made
a bit more generic...

> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index afb9100c50..d32c6e7549 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -2621,6 +2621,7 @@ virStringListHasString;
>  virStringListJoin;
>  virStringListLength;
>  virStringListRemove;
> +virStringMatch;
>  virStringReplace;
>  virStringSearch;
>  virStringSortCompare;
> diff --git a/src/util/virstring.c b/src/util/virstring.c
> index 335e773d78..b95a8926bd 100644
> --- a/src/util/virstring.c
> +++ b/src/util/virstring.c
> @@ -979,6 +979,40 @@ virStringSearch(const char *str,
>  }
>  
>  /**
> + * virStringMatch:
> + * @str: string to match
> + * @regexp: POSIX Extended regular expression pattern used for matching
> + *
> + * Performs a POSIX extended regex search against a string.
> + * Returns 0 on match, -1 on error, 1 on no match.
> + */
> +int
> +virStringMatch(const char *str,
> +               const char *regexp)
> +{
> +    regex_t re;
> +    int ret = -1;
> +    int rv;
> +
> +    VIR_DEBUG("match '%s' for '%s'", str, regexp);
> +
> +    if ((rv = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB)) != 0) {

Why not pass the last arg as @flags

> +        char error[100];
> +        regerror(rv, &re, error, sizeof(error));
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("error while compiling regular expression '%s': %s"),
> +                       regexp, error);
> +        return -1;
> +    }
> +
> +    if ((ret = regexec(&re, str, 0, NULL, 0)) != 0)

and perhaps the 3rd/4th args as params...

Could lead to some reuse of this particular function by others that also
call regcomp and regexec (virStorageBackendLogicalParseVolExtents has an
example of the args to regexec)

John
> +        ret = 1;
> +
> +    regfree(&re);
> +    return ret;
> +}
> +
> +/**
>   * virStringReplace:
>   * @haystack: the source string to process
>   * @oldneedle: the substring to locate
> diff --git a/src/util/virstring.h b/src/util/virstring.h
> index c545ca3f0d..3221d99752 100644
> --- a/src/util/virstring.h
> +++ b/src/util/virstring.h
> @@ -274,6 +274,9 @@ ssize_t virStringSearch(const char *str,
>                          char ***matches)
>      ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
>  
> +int virStringMatch(const char *str,
> +                   const char *regexp);
> +
>  char *virStringReplace(const char *haystack,
>                         const char *oldneedle,
>                         const char *newneedle)
> diff --git a/tests/virstringtest.c b/tests/virstringtest.c
> index 96bc79f832..f8402cd163 100644
> --- a/tests/virstringtest.c
> +++ b/tests/virstringtest.c
> @@ -480,6 +480,38 @@ testStringSearch(const void *opaque)
>  }
>  
>  
> +struct stringMatchData {
> +    const char *str;
> +    const char *regexp;
> +    bool expectMatch;
> +};
> +
> +static int
> +testStringMatch(const void *opaque)
> +{
> +    const struct stringMatchData *data = opaque;
> +    int rv;
> +
> +    rv = virStringMatch(data->str, data->regexp);
> +
> +    if (data->expectMatch) {
> +        if (rv != 0) {
> +            fprintf(stderr, "expected match for '%s' on '%s' but got no match\n",
> +                    data->regexp, data->str);
> +            return -1;
> +        }
> +    } else {
> +        if (rv != 1) {
> +            fprintf(stderr, "expected no match for '%s' on '%s' but got match\n",
> +                    data->regexp, data->str);
> +            return -1;
> +        }
> +    }
> +
> +    return 0;
> +}
> +
> +
>  struct stringReplaceData {
>      const char *haystack;
>      const char *oldneedle;
> @@ -803,6 +835,21 @@ mymain(void)
>      const char *matches3[] = { "foo", "bar" };
>      TEST_SEARCH("1foo2bar3eek", "([a-z]+)", 2, 2, matches3, false);
>  
> +#define TEST_MATCH(s, r, m)                                                 \
> +    do {                                                                    \
> +        struct stringMatchData data = {                                     \
> +            .str = s,                                                       \
> +            .regexp = r,                                                    \
> +            .expectMatch = m,                                               \
> +        };                                                                  \
> +        if (virTestRun("virStringMatch " s, testStringMatch, &data) < 0)    \
> +            ret = -1;                                                       \
> +    } while (0)
> +
> +    TEST_MATCH("foo", "foo", true);
> +    TEST_MATCH("foobar", "f[o]+", true);
> +    TEST_MATCH("foobar", "^f[o]+$", false);
> +
>  #define TEST_REPLACE(h, o, n, r)                                             \
>      do {                                                                     \
>          struct stringReplaceData data = {                                    \
> 




More information about the libvir-list mailing list