|
|
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 |
|