[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