[libvirt] [PATCH 1/2] Add virStringSearch method for regex matching

Ján Tomko jtomko at redhat.com
Thu Feb 20 10:52:19 UTC 2014


On 02/19/2014 09:36 PM, Daniel P. Berrange wrote:
> From: Manuel VIVES <manuel.vives at diateam.net>
> 
> Add a virStringSearch method to virstring.{c,h} which performs
> a regex match against a string and returns the matching substrings.
> 
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
>  po/POTFILES.in           |   1 +
>  src/libvirt_private.syms |   1 +
>  src/util/virstring.c     | 102 +++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/virstring.h     |   7 ++++
>  tests/virstringtest.c    | 100 ++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 211 insertions(+)
> 
> @@ -645,3 +647,103 @@ int virStringSortRevCompare(const void *a, const void *b)
>  
>      return strcmp(*sb, *sa);
>  }
> +
> +/**
> + * virStringSearch:
> + * @str: string to search
> + * @regexp: POSIX Extended regular expression pattern used for matching
> + * @max_matches: maximum number of substrings to return
> + * @result: pointer to an array to be filled with NULL terminated list of matches
> + *
> + * Performs a POSIX extended regex search against a string and return all matching substrings.
> + * The @result value should be freed with  virStringFreeList() when no longer

Double space before 'virStringFreeList'.

> + * required.
> + *
> + * @code
> + *  char *source = "6853a496-1c10-472e-867a-8244937bd6f0
> + *                  773ab075-4cd7-4fc2-8b6e-21c84e9cb391
> + *                  bbb3c75c-d60f-43b0-b802-fd56b84a4222
> + *                  60c04aa1-0375-4654-8d9f-e149d9885273
> + *                  4548d465-9891-4c34-a184-3b1c34a26aa8";
> + *  char **matches = NULL;
> + *  virSearchRegex(source,

The function is now renamed.

> + *                 "([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})",
> + *                  3,
> + *                  &matches);
> + *
> + *  // matches[0] == "4548d465-9891-4c34-a184-3b1c34a26aa8";
> + *  // matches[1] == "6853a496-1c10-472e-867a-8244937bd6f0";
> + *  // matches[2] == "773ab075-4cd7-4fc2-8b6e-21c84e9cb391"
> + *  // matches[3] == NULL;

And these matches are wrong.

> + *
> + *  virStringFreeList(matches);
> + * @endcode
> + *
> + * Returns: -1 on error, or number of matches
> + */
> +ssize_t
> +virStringSearch(const char *str,
> +                const char *regexp,
> +                size_t max_matches,
> +                char ***matches)
> +{
> +    regex_t re;
> +    regmatch_t rem;
> +    size_t nmatches = 0;
> +    ssize_t ret = -1;
> +    int rv = -1;
> +
> +    *matches = NULL;
> +
> +    VIR_DEBUG("search '%s' for '%s'", str, regexp);
> +
> +    if ((rv = regcomp(&re, regexp, REG_EXTENDED)) != 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("Error while compiling regular expression '%s': %d"),
> +                       regexp, rv);

Using 'regerror' instead of a numeric error code would be nicer.

> +        return -1;
> +    }
> +
> +    if (re.re_nsub != 1) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("Regular expression '%s' must have exactly 1 match group, not %zu"),
> +                       regexp, re.re_nsub);
> +        goto cleanup;
> +    }
> +
> +    /* '*matches' must always be NULL terminated in every iteration
> +     * of the loop, so start by allocating 1 element
> +     */
> +    if (VIR_EXPAND_N(*matches, nmatches, 1) < 0)
> +        goto cleanup;
> +

> diff --git a/tests/virstringtest.c b/tests/virstringtest.c
> index c6adf9f..b8c6115 100644
> --- a/tests/virstringtest.c
> +++ b/tests/virstringtest.c
> @@ -274,6 +274,70 @@ testStringSortCompare(const void *opaque ATTRIBUTE_UNUSED)
>  }
>  
>  
> +struct stringSearchData {
> +    const char *str;
> +    const char *regexp;
> +    size_t maxMatches;
> +    size_t expectNMatches;
> +    const char **expectMatches;
> +    bool expectError;
> +};
> +
> +static int
> +testStringSearch(const void *opaque ATTRIBUTE_UNUSED)
> +{
> +    const struct stringSearchData *data = opaque;
> +    char **matches = NULL;
> +    ssize_t nmatches;
> +    int ret;

ret = -1;

ACK with or without regerror.

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/a412b942/attachment-0001.sig>


More information about the libvir-list mailing list