[PATCH 06/11] xfree86: Refactor InputClass matching code
Jamey Sharp
jamey at minilop.net
Thu May 20 09:40:06 PDT 2010
Cool, that's a nice refactoring. In MatchAttrToken you could go a
little further even, replacing "match = TRUE" with "return TRUE" and
"return match" with "return FALSE", but either way,
Reviewed-by: Jamey Sharp <jamey at minilop.net>
On Thu, May 20, 2010 at 7:09 AM, Dan Nicholson <dbn.lists at gmail.com> wrote:
> 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
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
>
More information about the xorg-devel
mailing list