xserver: Introduce negated conditions in Match patterns

When processing input devices, it is useful to determine not only which
attributes are to be accepted, but also which are to be rejected. Hence we 
introduce
an '!' prefix, before a pattern, which means that if an attribute matches this
pattern, then the respective device is rejected by this InputClass. Hence an
entry can look as follows:
    MatchProduct "good&!bad|!bee&honey"
which is in fact a disjunctive normal form.

Signed-off-by: Oleh Nykyforchyn <[email protected]>
---
 hw/xfree86/common/xf86Xinput.c |    5 +++--
 hw/xfree86/parser/InputClass.c |   10 ++++++++++
 hw/xfree86/parser/xf86Parser.h |    1 +
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index e065876..3a16dc0 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -509,7 +509,8 @@ MatchAttrToken(const char *attr, struct list *groups)
         Bool match = TRUE;
 
         list_for_each_entry(pattern, &group->patterns, entry) {
-            match = match && match_token(attr, pattern);
+            match = match &&
+                (!match_token(attr, pattern) == pattern->is_negated);
             if (pattern->is_last) {
             /* last pattern in a conjunction, i.e. &-separated sequence */
                 if (match)
@@ -520,7 +521,7 @@ MatchAttrToken(const char *attr, struct list *groups)
         }
         return FALSE;
       new_group:
-        continue;
+        continue ;
     }
 
     /* All the entries in the list matched the attribute */
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 5794327..2d78f05 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -67,6 +67,8 @@ xf86ConfigSymTabRec InputClassTab[] =
 #define LOG_OR '|'
 #define LOG_AND '&'
 
+#define NEG_FLAG '!'
+
 
 static void
 free_group(xf86MatchGroup *group)
@@ -110,6 +112,12 @@ create_group(const char *str,
     }
     list_add(&pattern->entry, &group->patterns);
 
+    /* Pattern starting with '!' should NOT be matched */
+    if (*str == NEG_FLAG) {
+        pattern->is_negated = TRUE;
+        str++;
+    }
+
     pattern->mode = pref_mode;
 
     n = strcspn(str, sep);
@@ -327,6 +335,8 @@ print_pattern(FILE * cf, const xf86MatchPattern *pattern)
 {
     if (!pattern) return;
 
+    if (pattern->is_negated)
+        fprintf(cf, "%c", NEG_FLAG);
     if (pattern->mode == MATCH_IS_INVALID)
         fprintf(cf, "invalid:");
     if (pattern->str)
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index d10d421..6a42161 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -361,6 +361,7 @@ typedef struct
 {
        struct list entry;
        Bool is_last;
+       Bool is_negated;
        xf86MatchMode mode;
        char *str;
 }
-- 
1.7.4.4

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to