On 02/19/2014 09:36 PM, Daniel P. Berrange wrote: > From: Manuel VIVES <manuel.vives@xxxxxxxxxxx> > > 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@xxxxxxxxxx> > --- > 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
Attachment:
signature.asc
Description: OpenPGP digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list