From: David Lutterkort <[email protected]>

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

_______________________________________________
augeas-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/augeas-devel

Reply via email to