[PATCH xfree86] Signed-off-by: Oleh Nykyforchyn <oleh.nyk at gmail.com>

Oleh Nykyforchyn oleh.nyk at gmail.com
Wed May 25 05:08:32 PDT 2011


On Wed, 25 May 2011 16:14:42 +1000
Peter Hutterer <peter.hutterer at who-t.net> wrote:

> I believe | is used frequently in regular expressions, so using it as
> decision over regex or simple is dangerous. we can't use slash either, there
> are likely a few configurations out there already.
> My suggestion is simply prefixing with "re:". I guess there's very few
> configurations out there that need exactly that match and it makes it very
> clear that this match is a regular expression
> 
>     MatchProduct "re:[^ a-z]{4}|(x|y)"

Nice, short and intuitive. I modified my patch to use this idea, and the code
is simpler and clearer now. A piece of Xorg.0.log and the result is below:

[  2959.284] (II) config/udev: Adding input device Power Button (/dev/input/event2)
[  2959.285] (**) Applying regex ".implicit." to attribute "Radeon"
[  2959.285] (**) Applying regex "^R.d[a-z]*$" to attribute "Radeon"
[  2959.285] (**) Applying regex ".implicit." to attribute "Radeon"
[  2959.285] (**) Applying regex "^R.d[a-z]*$" to attribute "Radeon"
[  2959.285] (**) Power Button: Applying InputClass "Keyboard0"

Statements were:
     MatchLayout "re:.implicit."
     MatchLayout "re:^R.d[a-z]*$"
To tell the truth, I have no idea why each match is repeated twice, but it works.

The patch itself:
---------------------------------------

Add option to use extended regex expresssions in Match* statements

If a pattern list is of the form "re:str", then str is treated
as a single extended regular expression

Signed-off-by: Oleh Nykyforchyn <oleh.nyk at gmail.com>
---
 hw/xfree86/common/xf86Xinput.c |   25 +++++++++++++++++++
 hw/xfree86/parser/InputClass.c |   53 +++++++++++++++++++++++++++++++++-------
 2 files changed, 69 insertions(+), 9 deletions(-)

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 88cf292..0b90b5b 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -85,6 +85,9 @@
 #include <ptrveloc.h>          /* dix pointer acceleration */
 #include <xserver-properties.h>
 
+#include <sys/types.h>  /* MatchAttrToken */
+#include <regex.h>
+
 #ifdef XFreeXDGA
 #include "dgaproc.h"
 #endif
@@ -509,6 +512,28 @@ MatchAttrToken(const char *attr, struct list *patterns,
         char * const *cur;
         Bool match = FALSE;
 
+        cur = group->values;
+        if ((cur[0]) && (!*cur[0]) && /* cur[0] == "", can never come out of strtok() */
+            (cur[1]) &&               /* cur[1] == regex */
+            (cur[2] == NULL)) {
+            /* Treat this statement as a regex match */
+            regex_t buf;
+            int r;
+            r = regcomp(&buf, cur[1], REG_EXTENDED | REG_NOSUB);
+            if (r) { /* bad regex */
+                regfree(&buf);
+                xf86Msg(X_ERROR, "Wrong regex: \"%s\"\n", cur[1]);
+                return FALSE;
+            }
+            xf86Msg(X_CONFIG, "Applying regex \"%s\" to attribute \"%s\"\n", cur[1], attr);
+            r = regexec(&buf, attr, 0, NULL, 0);
+            regfree(&buf);
+            if (r)
+                return FALSE;
+            else
+                return TRUE;
+        }
+
         for (cur = group->values; *cur; cur++) {
             if (**cur == '!') {
             /*
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 3f80170..78a9446 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -66,6 +66,39 @@ xf86ConfigSymTabRec InputClassTab[] =
 
 #define TOKEN_SEP "|"
 
+/*
+ * Tokenize a string into a NULL terminated array of strings. The same that
+ * xstrtokenize unless the string starts with "re:", then the rest of
+ * the string is treated as a single extended regex, and
+ * {"", regex, NULL} is returned.
+ */
+static char**
+rstrtokenize(const char *str, const char *separators)
+{
+    if (!str)
+        return NULL;
+    if (!strncmp(str,"re:",3)){
+        char **list;
+
+        list = calloc(3, sizeof(*list));
+        if (!list)
+            return NULL;
+        list[0] = strdup("");
+        list[1] = calloc(strlen(str)-2, sizeof(char));
+        if (!list[0] || !list[1])
+            goto error;
+        strcpy(list[1], str+3);
+        return list;
+
+    error:
+        if (list[0]) free(list[0]);
+        if (list[1]) free(list[1]);
+        free(list);
+        return NULL;
+    }
+    return xstrtokenize(str, separators);
+}
+
 static void
 add_group_entry(struct list *head, char **values)
 {
@@ -127,55 +160,55 @@ xf86parseInputClassSection(void)
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchProduct");
             add_group_entry(&ptr->match_product,
-                            xstrtokenize(val.str, TOKEN_SEP));
+                            rstrtokenize(val.str, TOKEN_SEP));
             break;
         case MATCH_VENDOR:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchVendor");
             add_group_entry(&ptr->match_vendor,
-                            xstrtokenize(val.str, TOKEN_SEP));
+                            rstrtokenize(val.str, TOKEN_SEP));
             break;
         case MATCH_DEVICE_PATH:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchDevicePath");
             add_group_entry(&ptr->match_device,
-                            xstrtokenize(val.str, TOKEN_SEP));
+                            rstrtokenize(val.str, TOKEN_SEP));
             break;
         case MATCH_OS:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchOS");
             add_group_entry(&ptr->match_os,
-                            xstrtokenize(val.str, TOKEN_SEP));
+                            rstrtokenize(val.str, TOKEN_SEP));
             break;
         case MATCH_PNPID:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchPnPID");
             add_group_entry(&ptr->match_pnpid,
-                            xstrtokenize(val.str, TOKEN_SEP));
+                            rstrtokenize(val.str, TOKEN_SEP));
             break;
         case MATCH_USBID:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchUSBID");
             add_group_entry(&ptr->match_usbid,
-                            xstrtokenize(val.str, TOKEN_SEP));
+                            rstrtokenize(val.str, TOKEN_SEP));
             break;
         case MATCH_DRIVER:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchDriver");
             add_group_entry(&ptr->match_driver,
-                            xstrtokenize(val.str, TOKEN_SEP));
+                            rstrtokenize(val.str, TOKEN_SEP));
             break;
         case MATCH_TAG:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchTag");
             add_group_entry(&ptr->match_tag,
-                            xstrtokenize(val.str, TOKEN_SEP));
+                            rstrtokenize(val.str, TOKEN_SEP));
             break;
         case MATCH_LAYOUT:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchLayout");
             add_group_entry(&ptr->match_layout,
-                            xstrtokenize(val.str, TOKEN_SEP));
+                            rstrtokenize(val.str, TOKEN_SEP));
             break;
         case MATCH_IS_KEYBOARD:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
-- 
1.6.4



Oleh


More information about the xorg-devel mailing list