[PATCH 3/4] xserver: Use regular expressions in Match entries

Oleh Nykyforchyn oleh.nyk at gmail.com
Sat Jun 4 22:52:47 PDT 2011


Use regular expressions in Match entries

Signed-off-by: Oleh Nykyforchyn <oleh.nyk at gmail.com>
---
 hw/xfree86/common/xf86Xinput.c |   22 ++++++++++++++++++++--
 hw/xfree86/parser/InputClass.c |   17 ++++++++++++++++-
 hw/xfree86/parser/xf86Parser.h |    7 ++++++-
 3 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index f86b021..b1f12b8 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -445,7 +445,9 @@ HostOS(void)
 
 /*
  * Match an attribute against a pattern. Matching mode is
- * determined by pattern->mode member.
+ * determined by pattern->mode member. If the mode is REGEX,
+ * then regex_t is allocated and compiled only during
+ * the first call, to save time and memory.
  */
 static int
 multi_match(const char *attr, xf86MatchPattern *pattern)
@@ -484,8 +486,24 @@ multi_match(const char *attr, xf86MatchPattern *pattern)
         case MATCH_IS_PATHNAME:
             return (strstr(attr, pattern->str)) ? -1 : 0;
 #endif
+        case MATCH_IS_REGEX:
         default:
-        /* Impossible */
+            if (pattern->regex == NULL) {
+                int r;
+                if ((pattern->regex = malloc(sizeof(regex_t))) == NULL) {
+                    pattern->mode = MATCH_IS_INVALID;
+                    return 0;
+                }
+                r = regcomp(pattern->regex, pattern->str, REG_EXTENDED | REG_NOSUB);
+                if (r) { /* Wrong regex */
+                    regfree(pattern->regex);
+                    free(pattern->regex);
+                    xf86Msg(X_ERROR, "Wrong regex: \"%s\"\n", pattern->str);
+                    pattern->mode = MATCH_IS_INVALID;
+                    return 0;
+                }
+            }
+            return (regexec(pattern->regex, attr,0, NULL, 0)) ? 0 : -1;
     }
 }
 
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 6093320..cf30a74 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -68,6 +68,8 @@ xf86ConfigSymTabRec InputClassTab[] =
 
 #define NEG_FLAG '!'
 
+#define REGEX_PREFIX "regex:"
+
 
 static void
 add_to_group(xf86MatchGroup **group, const char *str,
@@ -97,7 +99,13 @@ add_to_group(xf86MatchGroup **group, const char *str,
         str++;
     }
 
-    pattern->mode = pref_mode;
+    /* Check if there is a mode prefix */
+    if (!strncmp(str,REGEX_PREFIX,strlen(REGEX_PREFIX))) {
+        pattern->mode = MATCH_IS_REGEX;
+        str += strlen(REGEX_PREFIX);
+    }
+    else
+        pattern->mode = pref_mode;
 
     if ((next = index(str, TOKEN_SEP)))
         n = next-str;
@@ -121,6 +129,10 @@ free_group(xf86MatchGroup *group)
     list_for_each_entry_safe(pattern, next_pattern, &group->patterns, entry) {
         list_del(&pattern->entry);
         if (pattern->str) free(pattern->str);
+        if ((pattern->mode == MATCH_IS_REGEX) && pattern->regex) {
+            regfree(pattern->regex);
+            free(pattern->regex);
+        }
         free(pattern);
     }
     free(group);
@@ -340,6 +352,9 @@ print_pattern(FILE * cf, const xf86MatchPattern *pattern)
         fprintf(cf, "%c", NEG_FLAG);
     if (pattern->mode == MATCH_IS_INVALID)
         fprintf(cf, "invalid:");
+    else
+    if (pattern->mode == MATCH_IS_REGEX)
+        fprintf(cf, "regex:");
     if (pattern->str)
         fprintf(cf, "%s\"", pattern->str);
     else
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index ea6008f..205f6ac 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -68,6 +68,9 @@
 #include "xf86Optrec.h"
 #include "list.h"
 
+#include <sys/types.h>
+#include <regex.h>
+
 #define HAVE_PARSER_DECLS
 
 typedef struct
@@ -354,7 +357,8 @@ typedef enum
 	MATCH_IS_STRSTR,
 	MATCH_IS_STRCASESTR,
 	MATCH_IS_FILENAME,
-	MATCH_IS_PATHNAME
+	MATCH_IS_PATHNAME,
+	MATCH_IS_REGEX
 }
 xf86MatchMode;
 
@@ -364,6 +368,7 @@ typedef struct
 	Bool is_negated;
 	xf86MatchMode mode;
 	char *str;
+	regex_t *regex;
 }
 xf86MatchPattern;
 
-- 
1.7.0.1



More information about the xorg-devel mailing list