[augeas-devel] [PATCH 5/8] regexp: add make_regexp_from_glob to convert globs to regexps

lutter at redhat.com lutter at redhat.com
Sat May 7 01:12:53 UTC 2011


From: David Lutterkort <lutter at redhat.com>

---
 src/regexp.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/regexp.h |    3 +++
 2 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/src/regexp.c b/src/regexp.c
index b5978d2..f351799 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -134,6 +134,54 @@ struct regexp *make_regexp(struct info *info, char *pat, int nocase) {
     return regexp;
 }
 
+/* Take a POSIX glob and turn it into a regexp. The regexp is constructed
+ * by doing the following translations of characters in the string:
+ *  * -> .*
+ *  ? -> .
+ *  leave characters escaped with a backslash alone
+ *  escape any of ".|{}()+^$" with a backslash
+ *
+ * Note that that ignores some of the finer points of globs, like
+ * complementation.
+ */
+struct regexp *make_regexp_from_glob(struct info *info, const char *glob) {
+    static const char *const special = ".|{}()+^$";
+    int newlen = strlen(glob);
+    char *pat = NULL;
+
+    for (const char *s = glob; *s; s++) {
+        if (*s == '\\' && *(s+1))
+            s += 1;
+        else if (*s == '*')
+            newlen += 1;
+        else if (strchr(special, *s) != NULL)
+            newlen += 1;
+    }
+
+    if (ALLOC_N(pat, newlen + 1) < 0)
+        return NULL;
+
+    char *t = pat;
+    for (const char *s = glob; *s; s++) {
+        if (*s == '\\' && *(s+1)) {
+            *t++ = *s++;
+            *t++ = *s;
+        } else if (*s == '*') {
+            *t++ = '.';
+            *t++ = '*';
+        } else if (*s == '?') {
+            *t++ = '.';
+        } else if (strchr(special, *s) != NULL) {
+            *t++ = '\\';
+            *t++ = *s;
+        } else {
+            *t++ = *s;
+        }
+    }
+
+    return make_regexp(info, pat, 0);
+}
+
 void free_regexp(struct regexp *regexp) {
     if (regexp == NULL)
         return;
diff --git a/src/regexp.h b/src/regexp.h
index e770735..0b2fd1d 100644
--- a/src/regexp.h
+++ b/src/regexp.h
@@ -55,6 +55,9 @@ int regexp_is_empty_pattern(struct regexp *r);
  */
 struct regexp *make_regexp_literal(struct info *info, const char *text);
 
+/* Make a regexp from a glob pattern */
+struct regexp *make_regexp_from_glob(struct info *info, const char *glob);
+
 /* Do not call directly, use UNREF instead */
 void free_regexp(struct regexp *regexp);
 
-- 
1.7.4.4




More information about the augeas-devel mailing list