---
po/POTFILES.in | 1 +
src/libvirt_private.syms | 1 +
src/util/virstring.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/virstring.h | 3 ++
4 files changed, 102 insertions(+)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 49dfc9c..ed09fc1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -189,6 +189,7 @@ src/util/virscsi.c
src/util/virsocketaddr.c
src/util/virstatslinux.c
src/util/virstoragefile.c
+src/util/virstring.c
src/util/virsysinfo.c
src/util/virerror.c
src/util/virerror.h
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 2dbb8f8..14ad8f4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1751,6 +1751,7 @@ virStorageFileResize;
# util/virstring.h
virArgvToString;
virAsprintfInternal;
+virSearchRegex;
virSkipSpaces;
virSkipSpacesAndBackslash;
virSkipSpacesBackwards;
diff --git a/src/util/virstring.c b/src/util/virstring.c
index 8d0ca70..3c93450 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <regex.h>
#include "c-ctype.h"
#include "virstring.h"
@@ -645,3 +646,99 @@ int virStringSortRevCompare(const void *a, const void *b)
return strcmp(*sb, *sa);
}
+
+/**
+ * virSearchRegex:
+ * Allows you to get the nth occurrence of a substring in sourceString which matches
+ * a POSIX Extended regular expression pattern.
+ * If there is no substring, result is not modified.
+ * return -1 on error, 0 if not found and 1 if found.
+ *
+ * @sourceString: String to parse
+ * @occurrence: return occurrence 'n' (starting from 0) of a sub-string that
+ * matches the pattern.
+ * @regexp: POSIX Extended regular expression pattern used for matching
+ * @result: nth occurrence substring matching the @regexp pattern
+ * @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 *ret1=NULL;
+ char *ret2=NULL;
+ char *ret3=NULL;
+ virSearchRegex(source,
+ 4,
+
"([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})",
+ &ret1);
+ //ret1 = "4548d465-9891-4c34-a184-3b1c34a26aa8"
+ virSearchRegex(source,
+ 0,
+
"([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})",
+ &ret2);
+ //ret2 = "6853a496-1c10-472e-867a-8244937bd6f0"
+ virSearchRegex(source,
+ 1,
+
"([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})",
+ &ret3);
+ //ret3 = "773ab075-4cd7-4fc2-8b6e-21c84e9cb391"
+ * @endcode
+ */
+
+int
+virSearchRegex(const char *sourceString,
+ unsigned int occurrence,
+ const char *regexp,
+ char **result)
+{
+ regex_t pregUuidBracket;
+ size_t i = 0;
+ size_t nmatch = 0;
+ regmatch_t *pmatch = NULL;
+ int ret = -1;
+ int regError = -1;
+
+ regError = regcomp(&pregUuidBracket, regexp, REG_EXTENDED);
+ if (regError != 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Error while compiling regular expression: %d"),
+ regError);
+ goto cleanup;
+ }
+ nmatch = pregUuidBracket.re_nsub;
+ if (VIR_ALLOC_N(pmatch, nmatch) < 0)
+ goto cleanup;
+
+ while (i < (occurrence+1)) {
+ if (regexec(&pregUuidBracket, sourceString, nmatch, pmatch, 0) == 0) {
+ regoff_t start = pmatch[0].rm_so;
+ regoff_t end = pmatch[0].rm_eo;
+ if (i == occurrence ||
+ (occurrence > i && regexec(&pregUuidBracket,
&sourceString[end],
+ nmatch, pmatch, 0) != 0)) {
+ /* We copy only if i == position (so that it is the uuid we're
looking for),
+ * or position > i AND there is no matches left in the rest of the
string
+ * (this is the case where we give a biggest @occurence than the
+ * number of matches and we want to return the last one)
+ */
+ if (VIR_STRNDUP(*result, sourceString + start, end - start) < 0)
+ goto cleanup;
+
+ ret = 1;
+ goto cleanup;
+ }
+ sourceString = &sourceString[end];
+ } else {
+ break;
+ ret = 0;
+ goto cleanup;
+ }
+ ++i;
+ }
+
+cleanup:
+ regfree(&pregUuidBracket);
+ VIR_FREE(pmatch);
+ return ret;
+}
diff --git a/src/util/virstring.h b/src/util/virstring.h
index 13a6e5a..fe05403 100644
--- a/src/util/virstring.h
+++ b/src/util/virstring.h
@@ -226,4 +226,7 @@ size_t virStringListLength(char **strings);
int virStringSortCompare(const void *a, const void *b);
int virStringSortRevCompare(const void *a, const void *b);
+int virSearchRegex(const char *sourceString, unsigned int occurrence, const char *regexp,
char **result);
+
+
#endif /* __VIR_STRING_H__ */
--
1.7.10.4