xfree86: Refactor InputClass matching code

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@gmail.com>
Reviewed-by: Jamey Sharp <jamey at minilop.net>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Dan Nicholson 2010-06-07 20:39:52 -07:00 committed by Peter Hutterer
parent d09bc8f8e5
commit 9b30fa9f8f

View File

@ -496,6 +496,48 @@ AddOtherInputDevices(void)
{
}
static int
match_substring(const char *attr, const char *pattern)
{
return (strstr(attr, pattern)) ? 0 : -1;
}
#ifdef HAVE_FNMATCH_H
static int
match_path_pattern(const char *attr, const char *pattern)
{
return fnmatch(pattern, attr, FNM_PATHNAME);
}
#else
#define match_path_pattern match_substring
#endif
/*
* Match an attribute against a NULL terminated list of patterns. If any
* pattern is matched, return TRUE.
*/
static Bool
MatchAttrToken(const char *attr, char **patterns,
int (*compare)(const char *attr, const char *pattern))
{
char **cur;
/* 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 */
for (cur = patterns; *cur; cur++)
if ((*compare)(attr, *cur) == 0)
return TRUE;
return FALSE;
}
/*
* Classes without any Match statements match all devices. Otherwise, all
* statements must match.
@ -504,67 +546,39 @@ static Bool
InputClassMatches(const XF86ConfInputClassPtr iclass,
const InputAttributes *attrs)
{
char **cur;
/* MatchProduct substring */
if (!MatchAttrToken(attrs->product, iclass->match_product, match_substring))
return FALSE;
/* MatchVendor substring */
if (!MatchAttrToken(attrs->vendor, iclass->match_vendor, match_substring))
return FALSE;
/* MatchDevicePath pattern */
if (!MatchAttrToken(attrs->device, iclass->match_device, match_path_pattern))
return FALSE;
/*
* MatchTag string
* See if any of the device's tags match any of the MatchTag tokens.
*/
if (iclass->match_tag) {
char * const *tag;
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 (iclass->match_tag) {
if (!attrs->tags)
return FALSE;
for (cur = iclass->match_tag, match = FALSE; *cur && !match; cur++) {
char * const *tag;
for(tag = attrs->tags; *tag; tag++) {
if (!strcmp(*tag, *cur)) {
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;
@ -583,6 +597,7 @@ InputClassMatches(const XF86ConfInputClassPtr iclass,
if (iclass->is_touchscreen.set &&
iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
return FALSE;
return TRUE;
}