render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
6d3351
From a05097ee436b03de9280a9ae25f85a150ddaa327 Mon Sep 17 00:00:00 2001
6d3351
Message-Id: <a05097ee436b03de9280a9ae25f85a150ddaa327@dist-git>
6d3351
From: Pavel Hrdina <phrdina@redhat.com>
6d3351
Date: Tue, 16 May 2017 11:46:11 +0200
6d3351
Subject: [PATCH] util: introduce virStringMatch
6d3351
6d3351
Simply tries to match the provided regex on a string and returns
6d3351
the result.  Useful if caller don't care about the matched substring
6d3351
and want to just test if some pattern patches a string.
6d3351
6d3351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
6d3351
(cherry picked from commit f15f155403e36a66e3568676105fdca725ad2c52)
6d3351
6d3351
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1446980
6d3351
6d3351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
6d3351
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
6d3351
---
6d3351
 src/libvirt_private.syms |  1 +
6d3351
 src/util/virstring.c     | 32 ++++++++++++++++++++++++++++++++
6d3351
 src/util/virstring.h     |  3 +++
6d3351
 tests/virstringtest.c    | 47 +++++++++++++++++++++++++++++++++++++++++++++++
6d3351
 4 files changed, 83 insertions(+)
6d3351
6d3351
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
6d3351
index 134d4a832..06c338384 100644
6d3351
--- a/src/libvirt_private.syms
6d3351
+++ b/src/libvirt_private.syms
6d3351
@@ -2599,6 +2599,7 @@ virStringListHasString;
6d3351
 virStringListJoin;
6d3351
 virStringListLength;
6d3351
 virStringListRemove;
6d3351
+virStringMatch;
6d3351
 virStringReplace;
6d3351
 virStringSearch;
6d3351
 virStringSortCompare;
6d3351
diff --git a/src/util/virstring.c b/src/util/virstring.c
6d3351
index 69abc267b..5b2be317b 100644
6d3351
--- a/src/util/virstring.c
6d3351
+++ b/src/util/virstring.c
6d3351
@@ -979,6 +979,38 @@ virStringSearch(const char *str,
6d3351
 }
6d3351
 
6d3351
 /**
6d3351
+ * virStringMatch:
6d3351
+ * @str: string to match
6d3351
+ * @regexp: POSIX Extended regular expression pattern used for matching
6d3351
+ *
6d3351
+ * Performs a POSIX extended regex match against a string.
6d3351
+ * Returns true on match, false on error or no match.
6d3351
+ */
6d3351
+bool
6d3351
+virStringMatch(const char *str,
6d3351
+               const char *regexp)
6d3351
+{
6d3351
+    regex_t re;
6d3351
+    int rv;
6d3351
+
6d3351
+    VIR_DEBUG("match '%s' for '%s'", str, regexp);
6d3351
+
6d3351
+    if ((rv = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB)) != 0) {
6d3351
+        char error[100];
6d3351
+        regerror(rv, &re, error, sizeof(error));
6d3351
+        VIR_WARN("error while compiling regular expression '%s': %s",
6d3351
+                 regexp, error);
6d3351
+        return false;
6d3351
+    }
6d3351
+
6d3351
+    rv = regexec(&re, str, 0, NULL, 0);
6d3351
+
6d3351
+    regfree(&re);
6d3351
+
6d3351
+    return rv == 0;
6d3351
+}
6d3351
+
6d3351
+/**
6d3351
  * virStringReplace:
6d3351
  * @haystack: the source string to process
6d3351
  * @oldneedle: the substring to locate
6d3351
diff --git a/src/util/virstring.h b/src/util/virstring.h
6d3351
index a5550e30d..0df03473a 100644
6d3351
--- a/src/util/virstring.h
6d3351
+++ b/src/util/virstring.h
6d3351
@@ -274,6 +274,9 @@ ssize_t virStringSearch(const char *str,
6d3351
                         char ***matches)
6d3351
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
6d3351
 
6d3351
+bool virStringMatch(const char *str,
6d3351
+                    const char *regexp);
6d3351
+
6d3351
 char *virStringReplace(const char *haystack,
6d3351
                        const char *oldneedle,
6d3351
                        const char *newneedle)
6d3351
diff --git a/tests/virstringtest.c b/tests/virstringtest.c
6d3351
index db1731f96..d27c8a5a8 100644
6d3351
--- a/tests/virstringtest.c
6d3351
+++ b/tests/virstringtest.c
6d3351
@@ -480,6 +480,38 @@ testStringSearch(const void *opaque)
6d3351
 }
6d3351
 
6d3351
 
6d3351
+struct stringMatchData {
6d3351
+    const char *str;
6d3351
+    const char *regexp;
6d3351
+    bool expectMatch;
6d3351
+};
6d3351
+
6d3351
+static int
6d3351
+testStringMatch(const void *opaque)
6d3351
+{
6d3351
+    const struct stringMatchData *data = opaque;
6d3351
+    bool match;
6d3351
+
6d3351
+    match = virStringMatch(data->str, data->regexp);
6d3351
+
6d3351
+    if (data->expectMatch) {
6d3351
+        if (!match) {
6d3351
+            fprintf(stderr, "expected match for '%s' on '%s' but got no match\n",
6d3351
+                    data->regexp, data->str);
6d3351
+            return -1;
6d3351
+        }
6d3351
+    } else {
6d3351
+        if (match) {
6d3351
+            fprintf(stderr, "expected no match for '%s' on '%s' but got match\n",
6d3351
+                    data->regexp, data->str);
6d3351
+            return -1;
6d3351
+        }
6d3351
+    }
6d3351
+
6d3351
+    return 0;
6d3351
+}
6d3351
+
6d3351
+
6d3351
 struct stringReplaceData {
6d3351
     const char *haystack;
6d3351
     const char *oldneedle;
6d3351
@@ -803,6 +835,21 @@ mymain(void)
6d3351
     const char *matches3[] = { "foo", "bar" };
6d3351
     TEST_SEARCH("1foo2bar3eek", "([a-z]+)", 2, 2, matches3, false);
6d3351
 
6d3351
+#define TEST_MATCH(s, r, m)                                                 \
6d3351
+    do {                                                                    \
6d3351
+        struct stringMatchData data = {                                     \
6d3351
+            .str = s,                                                       \
6d3351
+            .regexp = r,                                                    \
6d3351
+            .expectMatch = m,                                               \
6d3351
+        };                                                                  \
6d3351
+        if (virTestRun("virStringMatch " s, testStringMatch, &data) < 0)    \
6d3351
+            ret = -1;                                                       \
6d3351
+    } while (0)
6d3351
+
6d3351
+    TEST_MATCH("foo", "foo", true);
6d3351
+    TEST_MATCH("foobar", "f[o]+", true);
6d3351
+    TEST_MATCH("foobar", "^f[o]+$", false);
6d3351
+
6d3351
 #define TEST_REPLACE(h, o, n, r)                                             \
6d3351
     do {                                                                     \
6d3351
         struct stringReplaceData data = {                                    \
6d3351
-- 
6d3351
2.13.0
6d3351