[libvirt] [PATCHv6 1/5] virstring.h/c: Util method for finding regexp patterns in some strings

Manuel VIVES manuel.vives at diateam.net
Thu Jan 23 09:28:29 UTC 2014


---
 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 0359b2f..738cfb1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -188,6 +188,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 d1a58f9..68ca39d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1763,6 +1763,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




More information about the libvir-list mailing list