[PATCH 06/11] xfree86: Refactor InputClass matching code
Dan Nicholson
dbn.lists at gmail.com
Thu May 20 07:09:08 PDT 2010
InputClassMatches was starting to get a little hairy with all the loops
over the tokenized match strings. This adds code, but makes it easier to
read and add new matches.
Signed-off-by: Dan Nicholson <dbn.lists at gmail.com>
---
hw/xfree86/common/xf86Xinput.c | 121 +++++++++++++++++++++++-----------------
1 files changed, 70 insertions(+), 51 deletions(-)
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 3f1de8f..d72150b 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -496,74 +496,92 @@ AddOtherInputDevices(void)
{
}
+static int
+MatchSubstring(const char *attr, const char *pattern)
+{
+ return (strstr(pattern, attr)) ? 0 : -1;
+}
+
+#ifdef HAVE_FNMATCH_H
+static int
+MatchPathPattern(const char *attr, const char *pattern)
+{
+ return fnmatch(pattern, attr, FNM_PATHNAME);
+}
+#else
+#define MatchPathPattern MatchSubstring
+#endif
+
/*
- * Classes without any Match statements match all devices. Otherwise, all
- * statements must match.
+ * Match an attribute against a NULL terminated list of patterns. If any
+ * pattern is matched, return TRUE.
*/
static Bool
-InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
+MatchAttrToken(const char *attr, char **patterns,
+ int (*compare)(const char *attr, const char *pattern))
{
char **cur;
Bool match;
- if (iclass->match_product) {
- if (!attrs->product)
- return FALSE;
- /* see if any of the values match */
- for (cur = iclass->match_product, match = FALSE; *cur; cur++)
- if (strstr(attrs->product, *cur)) {
- match = TRUE;
- break;
- }
- if (!match)
- return FALSE;
- }
- if (iclass->match_vendor) {
- if (!attrs->vendor)
- return FALSE;
- /* see if any of the values match */
- for (cur = iclass->match_vendor, match = FALSE; *cur; cur++)
- if (strstr(attrs->vendor, *cur)) {
- match = TRUE;
- break;
- }
- if (!match)
- return FALSE;
- }
- if (iclass->match_device) {
- if (!attrs->device)
- return FALSE;
- /* see if any of the values match */
- for (cur = iclass->match_device, match = FALSE; *cur; cur++)
-#ifdef HAVE_FNMATCH_H
- if (fnmatch(*cur, attrs->device, FNM_PATHNAME) == 0) {
-#else
- if (strstr(attrs->device, *cur)) {
-#endif
- match = TRUE;
- break;
- }
- if (!match)
- return FALSE;
+ /* If there are no patterns, accept the match */
+ if (!patterns)
+ return TRUE;
+
+ /* If there are patterns but no attribute, reject the match */
+ if (!attr)
+ return FALSE;
+
+ /* Otherwise, iterate the patterns looking for a match */
+ match = FALSE;
+ for (cur = patterns; *cur; cur++) {
+ if ((*compare)(attr, *cur) == 0) {
+ match = TRUE;
+ break;
+ }
}
+ return match;
+}
+
+/*
+ * Classes without any Match statements match all devices. Otherwise, all
+ * statements must match.
+ */
+static Bool
+InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
+{
+ /* MatchProduct substring */
+ if (!MatchAttrToken(attrs->product, iclass->match_product, MatchSubstring))
+ return FALSE;
+
+ /* MatchVendor substring */
+ if (!MatchAttrToken(attrs->vendor, iclass->match_vendor, MatchSubstring))
+ return FALSE;
+
+ /* MatchDevicePath pattern */
+ if (!MatchAttrToken(attrs->device, iclass->match_device, MatchPathPattern))
+ return FALSE;
+
+ /*
+ * MatchTag string
+ * See if any of the device's tags match any of the MatchTag tokens.
+ */
if (iclass->match_tag) {
+ const char * const *tag;
+ Bool match;
+
if (!attrs->tags)
return FALSE;
-
- for (cur = iclass->match_tag, match = FALSE; *cur && !match; cur++) {
- const char * const *tag;
- for(tag = attrs->tags; *tag; tag++) {
- if (!strcmp(*tag, *cur)) {
- match = TRUE;
- break;
- }
+ for (tag = attrs->tags, match = FALSE; *tag; tag++) {
+ if (MatchAttrToken(*tag, iclass->match_tag, strcmp)) {
+ match = TRUE;
+ break;
}
}
-
if (!match)
return FALSE;
}
+ /* MatchIs* booleans */
if (iclass->is_keyboard.set &&
iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
return FALSE;
@@ -582,6 +600,7 @@ InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
if (iclass->is_touchscreen.set &&
iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
return FALSE;
+
return TRUE;
}
--
1.6.6.1
More information about the xorg-devel
mailing list