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

Pavel Hrdina phrdina at redhat.com
Thu May 11 15:49:53 UTC 2017


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(+)

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) {
+        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)
+        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 = {                                    \
-- 
2.12.2




More information about the libvir-list mailing list