[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