mirror of
https://github.com/X11Libre/xserver.git
synced 2026-04-14 17:18:09 +00:00
xserver: hw/xfree86/{common,parser}: use pattern groups for devices matching to classes
It is patch 3/5 of a series that refactors matching input and output devices to classes and extends possibilities to describe them, in particular, it allows use of regular expressions. This patch defines a function MatchAddrToken that actually matches an attribute against a list of pattern groups (in fact, Match... lines). It is used to check whether a particular input/optput class should be applied to a device, thus replacing the tangled and difficult to control code in InputClass.c and OutputClass.c. Signed-off-by: Oleh Nykyforchyn <oleh.nyk@gmail.com>
This commit is contained in:
committed by
Enrico Weigelt
parent
f7a892d7d0
commit
d4a7263940
@@ -528,82 +528,96 @@ HostOS(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
match_substring(const char *attr, const char *pattern)
|
||||
{
|
||||
return (strstr(attr, pattern)) ? 0 : -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FNMATCH_H
|
||||
static int
|
||||
match_pattern(const char *attr, const char *pattern)
|
||||
{
|
||||
return fnmatch(pattern, attr, 0);
|
||||
}
|
||||
#else
|
||||
#define match_pattern match_substring
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
/*
|
||||
* If no Layout section is found, xf86ServerLayout.id becomes "(implicit)"
|
||||
* It is convenient that "" in patterns means "no explicit layout"
|
||||
* Match an attribute against a pattern. Matching mode is
|
||||
* determined by pattern->mode member.
|
||||
*/
|
||||
|
||||
static int
|
||||
match_string_implicit(const char *attr, const char *pattern)
|
||||
match_token(const char *attr, xf86MatchPattern *pattern)
|
||||
{
|
||||
if (strlen(pattern)) {
|
||||
return strcmp(attr, pattern);
|
||||
}
|
||||
else {
|
||||
return strcmp(attr, "(implicit)");
|
||||
if ((!pattern) || (!attr))
|
||||
return 0;
|
||||
|
||||
switch (pattern->mode)
|
||||
{
|
||||
case MATCH_IS_INVALID:
|
||||
return 0;
|
||||
case MATCH_EXACT:
|
||||
return (strcmp(attr, pattern->str)) ? 0 : -1;
|
||||
case MATCH_EXACT_NOCASE:
|
||||
return (strcasecmp(attr, pattern->str)) ? 0 : -1;
|
||||
case MATCH_AS_SUBSTRING:
|
||||
return (strstr(attr, pattern->str)) ? -1 : 0;
|
||||
case MATCH_AS_SUBSTRING_NOCASE:
|
||||
return (strcasestr(attr, pattern->str)) ? -1 : 0;
|
||||
case MATCH_AS_FILENAME:
|
||||
#ifdef HAVE_FNMATCH_H
|
||||
return (fnmatch(pattern->str, attr, 0)) ? 0 : -1;
|
||||
#else
|
||||
LogMessageVerb(X_WARNING, 1, "Filename matching requested but unavailable for \"%s\", resorting to search for substring\n", pattern->str);
|
||||
pattern->mode = MATCH_AS_SUBSTRING;
|
||||
return (strcmp(attr, pattern->str)) ? 0 : -1;
|
||||
#endif
|
||||
|
||||
case MATCH_AS_PATHNAME:
|
||||
#ifdef HAVE_FNMATCH_H
|
||||
return (fnmatch(pattern->str, attr, FNM_PATHNAME)) ? 0 : -1;
|
||||
#else
|
||||
LogMessageVerb(X_WARNING, 1, "Pathname matching requested but unavailable for \"%s\", resorting to search for substring\n", pattern->str);
|
||||
pattern->mode = MATCH_AS_SUBSTRING;
|
||||
return (strcmp(attr, pattern->str)) ? 0 : -1;
|
||||
#endif
|
||||
case MATCH_SUBSTRINGS_SEQUENCE:
|
||||
default:
|
||||
{
|
||||
char* str = pattern->str;
|
||||
while (*str) {
|
||||
attr=strstr(attr, str);
|
||||
if (!attr) return 0;
|
||||
attr += strlen(str);
|
||||
str += strlen(str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Match an attribute against a list of NULL terminated arrays of patterns.
|
||||
* If a pattern in each list entry is matched, return TRUE.
|
||||
* Match an attribute against a list of xf86MatchGroup's.
|
||||
* Return TRUE only if each list entry is successful.
|
||||
*/
|
||||
static Bool
|
||||
MatchAttrToken(const char *attr, struct xorg_list *patterns,
|
||||
int (*compare) (const char *attr, const char *pattern))
|
||||
Bool
|
||||
MatchAttrToken(const char *attr, struct xorg_list *groups)
|
||||
{
|
||||
const xf86MatchGroup *group;
|
||||
xf86MatchGroup *group;
|
||||
xf86MatchPattern *pattern;
|
||||
|
||||
/* If there are no patterns, accept the match */
|
||||
if (xorg_list_is_empty(patterns))
|
||||
/* If there are no groups, accept the match */
|
||||
if (xorg_list_is_empty(groups))
|
||||
return TRUE;
|
||||
|
||||
/* If there are groups but no attribute, reject the match */
|
||||
if (!attr)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Iterate the list of patterns ensuring each entry has a
|
||||
* match. Each list entry is a separate Match line of the same type.
|
||||
* Otherwise, iterate the list of groups ensuring each entry has a
|
||||
* match. Each list entry is a list of patterns obtained from
|
||||
* a separate Match line.
|
||||
*/
|
||||
xorg_list_for_each_entry(group, patterns, entry) {
|
||||
char *const *cur;
|
||||
Bool is_negated = group->is_negated;
|
||||
Bool match = is_negated;
|
||||
xorg_list_for_each_entry(group, groups, entry) {
|
||||
Bool match = FALSE;
|
||||
|
||||
/* If there's a pattern but no attribute, we reject the match for a
|
||||
* MatchFoo directive, and accept it for a NoMatchFoo directive
|
||||
*/
|
||||
if (!attr)
|
||||
return is_negated;
|
||||
|
||||
for (cur = group->values; *cur; cur++)
|
||||
if ((*compare) (attr, *cur) == 0) {
|
||||
match = !is_negated;
|
||||
break;
|
||||
}
|
||||
if (!match)
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
/* It is enough to find one pattern matched by the attribute */
|
||||
match = ((!match_token(attr, pattern)) == pattern->is_negated);
|
||||
if (match)
|
||||
goto group_done;
|
||||
}
|
||||
group_done:
|
||||
if (match == group->is_negated)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -619,34 +633,34 @@ static Bool
|
||||
InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
|
||||
const InputAttributes * attrs)
|
||||
{
|
||||
const char *layout;
|
||||
|
||||
/* MatchProduct substring */
|
||||
if (!MatchAttrToken
|
||||
(attrs->product, &iclass->match_product, match_substring))
|
||||
if (!MatchAttrToken(attrs->product, &iclass->match_product))
|
||||
return FALSE;
|
||||
|
||||
/* MatchVendor substring */
|
||||
if (!MatchAttrToken(attrs->vendor, &iclass->match_vendor, match_substring))
|
||||
if (!MatchAttrToken(attrs->vendor, &iclass->match_vendor))
|
||||
return FALSE;
|
||||
|
||||
/* MatchDevicePath pattern */
|
||||
if (!MatchAttrToken
|
||||
(attrs->device, &iclass->match_device, match_path_pattern))
|
||||
if (!MatchAttrToken(attrs->device, &iclass->match_device))
|
||||
return FALSE;
|
||||
|
||||
/* MatchOS case-insensitive string */
|
||||
if (!MatchAttrToken(HostOS(), &iclass->match_os, strcasecmp))
|
||||
if (!MatchAttrToken(HostOS(), &iclass->match_os))
|
||||
return FALSE;
|
||||
|
||||
/* MatchPnPID pattern */
|
||||
if (!MatchAttrToken(attrs->pnp_id, &iclass->match_pnpid, match_pattern))
|
||||
if (!MatchAttrToken(attrs->pnp_id, &iclass->match_pnpid))
|
||||
return FALSE;
|
||||
|
||||
/* MatchUSBID pattern */
|
||||
if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern))
|
||||
if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid))
|
||||
return FALSE;
|
||||
|
||||
/* MatchDriver string */
|
||||
if (!MatchAttrToken(idev->driver, &iclass->match_driver, strcmp))
|
||||
if (!MatchAttrToken(idev->driver, &iclass->match_driver))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
@@ -660,7 +674,7 @@ InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
|
||||
if (!attrs->tags)
|
||||
return FALSE;
|
||||
for (tag = attrs->tags, match = FALSE; *tag; tag++) {
|
||||
if (MatchAttrToken(*tag, &iclass->match_tag, strcmp)) {
|
||||
if (MatchAttrToken(*tag, &iclass->match_tag)) {
|
||||
match = TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -669,12 +683,17 @@ InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* MatchLayout string */
|
||||
if (!xorg_list_is_empty(&iclass->match_layout)) {
|
||||
if (!MatchAttrToken(xf86ConfigLayout.id,
|
||||
&iclass->match_layout, match_string_implicit))
|
||||
/* MatchLayout string
|
||||
*
|
||||
* If no Layout section is found, xf86ServerLayout.id becomes "(implicit)"
|
||||
* It is convenient that "" in patterns means "no explicit layout"
|
||||
*/
|
||||
if (strcmp(xf86ConfigLayout.id,"(implicit)"))
|
||||
layout = xf86ConfigLayout.id;
|
||||
else
|
||||
layout = "";
|
||||
if (!MatchAttrToken(layout, &iclass->match_layout))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* MatchIs* booleans */
|
||||
if (iclass->is_keyboard.set &&
|
||||
|
||||
@@ -22,4 +22,6 @@ void xf86AddInputEventDrainCallback(CallbackProcPtr callback, void *param);
|
||||
|
||||
void xf86RemoveInputEventDrainCallback(CallbackProcPtr callback, void *param);
|
||||
|
||||
Bool MatchAttrToken(const char *attr, struct xorg_list *groups);
|
||||
|
||||
#endif /* _XSERVER__XF86XINPUT_H */
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "xf86Bus.h"
|
||||
#include "Pci.h"
|
||||
#include "xf86platformBus.h"
|
||||
#include "xf86Xinput_priv.h"
|
||||
#include "xf86Config.h"
|
||||
#include "xf86Crtc.h"
|
||||
|
||||
@@ -176,50 +177,13 @@ xf86_check_platform_slot(const struct xf86_platform_device *pd)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
MatchToken(const char *value, struct xorg_list *patterns,
|
||||
int (*compare)(const char *, const char *))
|
||||
{
|
||||
const xf86MatchGroup *group;
|
||||
|
||||
/* If there are no patterns, accept the match */
|
||||
if (xorg_list_is_empty(patterns))
|
||||
return TRUE;
|
||||
|
||||
/* If there are patterns but no attribute, reject the match */
|
||||
if (!value)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Otherwise, iterate the list of patterns ensuring each entry has a
|
||||
* match. Each list entry is a separate Match line of the same type.
|
||||
*/
|
||||
xorg_list_for_each_entry(group, patterns, entry) {
|
||||
Bool match = FALSE;
|
||||
char *const *cur;
|
||||
|
||||
for (cur = group->values; *cur; cur++) {
|
||||
if ((*compare)(value, *cur) == 0) {
|
||||
match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* All the entries in the list matched the attribute */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
OutputClassMatches(const XF86ConfOutputClassPtr oclass,
|
||||
struct xf86_platform_device *dev)
|
||||
{
|
||||
char *driver = dev->attribs->driver;
|
||||
|
||||
if (!MatchToken(driver, &oclass->match_driver, strcmp))
|
||||
if (!MatchAttrToken(driver, &oclass->match_driver))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -100,30 +100,13 @@ xf86freeInputClassList(XF86ConfInputClassPtr ptr)
|
||||
|
||||
#define CLEANUP xf86freeInputClassList
|
||||
|
||||
#define TOKEN_SEP "|"
|
||||
|
||||
enum MatchType {
|
||||
MATCH_NORMAL,
|
||||
MATCH_NEGATED,
|
||||
};
|
||||
|
||||
static void
|
||||
add_group_entry(struct xorg_list *head, char **values, enum MatchType type)
|
||||
{
|
||||
xf86MatchGroup *group = calloc(1, sizeof(xf86MatchGroup));
|
||||
if (group) {
|
||||
group->is_negated = (type == MATCH_NEGATED);
|
||||
group->values = values;
|
||||
xorg_list_add(&group->entry, head);
|
||||
}
|
||||
}
|
||||
|
||||
XF86ConfInputClassPtr
|
||||
xf86parseInputClassSection(void)
|
||||
{
|
||||
int has_ident = FALSE;
|
||||
int token;
|
||||
enum MatchType matchtype;
|
||||
Bool negated;
|
||||
xf86MatchGroup *group;
|
||||
|
||||
parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec)
|
||||
|
||||
@@ -139,7 +122,7 @@ xf86parseInputClassSection(void)
|
||||
xorg_list_init(&ptr->match_layout);
|
||||
|
||||
while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
|
||||
matchtype = MATCH_NORMAL;
|
||||
negated = FALSE;
|
||||
|
||||
switch (token) {
|
||||
case COMMENT:
|
||||
@@ -169,103 +152,121 @@ xf86parseInputClassSection(void)
|
||||
ptr->option_lst = xf86parseOption(ptr->option_lst);
|
||||
break;
|
||||
case NOMATCH_PRODUCT:
|
||||
matchtype = MATCH_NEGATED;
|
||||
negated = TRUE;
|
||||
/* fallthrough */
|
||||
case MATCH_PRODUCT:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
Error(QUOTE_MSG, "MatchProduct");
|
||||
add_group_entry(&ptr->match_product,
|
||||
xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
|
||||
matchtype);
|
||||
free(xf86_lex_val.str);
|
||||
else {
|
||||
group = xf86createMatchGroup(xf86_lex_val.str, MATCH_AS_SUBSTRING, negated);
|
||||
if (group)
|
||||
xorg_list_add(&group->entry, &ptr->match_product);
|
||||
free(xf86_lex_val.str);
|
||||
}
|
||||
break;
|
||||
case NOMATCH_VENDOR:
|
||||
matchtype = MATCH_NEGATED;
|
||||
negated = TRUE;
|
||||
/* fallthrough */
|
||||
case MATCH_VENDOR:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
Error(QUOTE_MSG, "MatchVendor");
|
||||
add_group_entry(&ptr->match_vendor,
|
||||
xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
|
||||
matchtype);
|
||||
free(xf86_lex_val.str);
|
||||
else {
|
||||
group = xf86createMatchGroup(xf86_lex_val.str, MATCH_AS_SUBSTRING, negated);
|
||||
if (group)
|
||||
xorg_list_add(&group->entry, &ptr->match_vendor);
|
||||
free(xf86_lex_val.str);
|
||||
}
|
||||
break;
|
||||
case NOMATCH_DEVICE_PATH:
|
||||
matchtype = MATCH_NEGATED;
|
||||
negated = TRUE;
|
||||
/* fallthrough */
|
||||
case MATCH_DEVICE_PATH:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
Error(QUOTE_MSG, "MatchDevicePath");
|
||||
add_group_entry(&ptr->match_device,
|
||||
xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
|
||||
matchtype);
|
||||
free(xf86_lex_val.str);
|
||||
else {
|
||||
group = xf86createMatchGroup(xf86_lex_val.str, MATCH_AS_PATHNAME, negated);
|
||||
if (group)
|
||||
xorg_list_add(&group->entry, &ptr->match_device);
|
||||
free(xf86_lex_val.str);
|
||||
}
|
||||
break;
|
||||
case NOMATCH_OS:
|
||||
matchtype = MATCH_NEGATED;
|
||||
negated = TRUE;
|
||||
/* fallthrough */
|
||||
case MATCH_OS:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
Error(QUOTE_MSG, "MatchOS");
|
||||
add_group_entry(&ptr->match_os, xstrtokenize(xf86_lex_val.str,
|
||||
TOKEN_SEP),
|
||||
matchtype);
|
||||
free(xf86_lex_val.str);
|
||||
else {
|
||||
group = xf86createMatchGroup(xf86_lex_val.str, MATCH_EXACT_NOCASE, negated);
|
||||
if (group)
|
||||
xorg_list_add(&group->entry, &ptr->match_os);
|
||||
free(xf86_lex_val.str);
|
||||
}
|
||||
break;
|
||||
case NOMATCH_PNPID:
|
||||
matchtype = MATCH_NEGATED;
|
||||
negated = TRUE;
|
||||
/* fallthrough */
|
||||
case MATCH_PNPID:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
Error(QUOTE_MSG, "MatchPnPID");
|
||||
add_group_entry(&ptr->match_pnpid,
|
||||
xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
|
||||
matchtype);
|
||||
free(xf86_lex_val.str);
|
||||
else {
|
||||
group = xf86createMatchGroup(xf86_lex_val.str, MATCH_AS_FILENAME, negated);
|
||||
if (group)
|
||||
xorg_list_add(&group->entry, &ptr->match_pnpid);
|
||||
free(xf86_lex_val.str);
|
||||
}
|
||||
break;
|
||||
case NOMATCH_USBID:
|
||||
matchtype = MATCH_NEGATED;
|
||||
negated = TRUE;
|
||||
/* fallthrough */
|
||||
case MATCH_USBID:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
Error(QUOTE_MSG, "MatchUSBID");
|
||||
add_group_entry(&ptr->match_usbid,
|
||||
xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
|
||||
matchtype);
|
||||
free(xf86_lex_val.str);
|
||||
else {
|
||||
group = xf86createMatchGroup(xf86_lex_val.str, MATCH_AS_FILENAME, negated);
|
||||
if (group)
|
||||
xorg_list_add(&group->entry, &ptr->match_usbid);
|
||||
free(xf86_lex_val.str);
|
||||
}
|
||||
break;
|
||||
case NOMATCH_DRIVER:
|
||||
matchtype = MATCH_NEGATED;
|
||||
negated = TRUE;
|
||||
/* fallthrough */
|
||||
case MATCH_DRIVER:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
Error(QUOTE_MSG, "MatchDriver");
|
||||
add_group_entry(&ptr->match_driver,
|
||||
xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
|
||||
matchtype);
|
||||
free(xf86_lex_val.str);
|
||||
else {
|
||||
group = xf86createMatchGroup(xf86_lex_val.str, MATCH_EXACT, negated);
|
||||
if (group)
|
||||
xorg_list_add(&group->entry, &ptr->match_driver);
|
||||
free(xf86_lex_val.str);
|
||||
}
|
||||
break;
|
||||
case NOMATCH_TAG:
|
||||
matchtype = MATCH_NEGATED;
|
||||
negated = TRUE;
|
||||
/* fallthrough */
|
||||
case MATCH_TAG:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
Error(QUOTE_MSG, "MatchTag");
|
||||
add_group_entry(&ptr->match_tag, xstrtokenize(xf86_lex_val.str,
|
||||
TOKEN_SEP),
|
||||
matchtype);
|
||||
free(xf86_lex_val.str);
|
||||
else {
|
||||
group = xf86createMatchGroup(xf86_lex_val.str, MATCH_EXACT, negated);
|
||||
if (group)
|
||||
xorg_list_add(&group->entry, &ptr->match_tag);
|
||||
free(xf86_lex_val.str);
|
||||
}
|
||||
break;
|
||||
case NOMATCH_LAYOUT:
|
||||
matchtype = MATCH_NEGATED;
|
||||
negated = TRUE;
|
||||
/* fallthrough */
|
||||
case MATCH_LAYOUT:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
Error(QUOTE_MSG, "MatchLayout");
|
||||
add_group_entry(&ptr->match_layout,
|
||||
xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
|
||||
matchtype);
|
||||
free(xf86_lex_val.str);
|
||||
else {
|
||||
group = xf86createMatchGroup(xf86_lex_val.str, MATCH_EXACT, negated);
|
||||
if (group)
|
||||
xorg_list_add(&group->entry, &ptr->match_layout);
|
||||
free(xf86_lex_val.str);
|
||||
}
|
||||
break;
|
||||
case MATCH_IS_KEYBOARD:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
@@ -348,10 +349,11 @@ xf86parseInputClassSection(void)
|
||||
}
|
||||
|
||||
void
|
||||
xf86printInputClassSection(FILE * cf, XF86ConfInputClassPtr ptr)
|
||||
xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr)
|
||||
{
|
||||
const xf86MatchGroup *group;
|
||||
char *const *cur;
|
||||
const xf86MatchPattern *pattern;
|
||||
Bool not_first;
|
||||
|
||||
while (ptr) {
|
||||
fprintf(cf, "Section \"InputClass\"\n");
|
||||
@@ -363,69 +365,95 @@ xf86printInputClassSection(FILE * cf, XF86ConfInputClassPtr ptr)
|
||||
fprintf(cf, "\tDriver \"%s\"\n", ptr->driver);
|
||||
|
||||
xorg_list_for_each_entry(group, &ptr->match_product, entry) {
|
||||
fprintf(cf, "\tMatchProduct \"");
|
||||
for (cur = group->values; *cur; cur++)
|
||||
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||
*cur);
|
||||
if (group->is_negated) fprintf(cf, "\tNoMatchProduct \"");
|
||||
else fprintf(cf, "\tMatchProduct \"");
|
||||
not_first = FALSE;
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
xf86printMatchPattern(cf, pattern, not_first);
|
||||
not_first = TRUE;
|
||||
}
|
||||
fprintf(cf, "\"\n");
|
||||
}
|
||||
xorg_list_for_each_entry(group, &ptr->match_vendor, entry) {
|
||||
fprintf(cf, "\tMatchVendor \"");
|
||||
for (cur = group->values; *cur; cur++)
|
||||
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||
*cur);
|
||||
if (group->is_negated) fprintf(cf, "\tNoMatchVendor \"");
|
||||
else fprintf(cf, "\tMatchVendor \"");
|
||||
not_first = FALSE;
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
xf86printMatchPattern(cf, pattern, not_first);
|
||||
not_first = TRUE;
|
||||
}
|
||||
fprintf(cf, "\"\n");
|
||||
}
|
||||
xorg_list_for_each_entry(group, &ptr->match_device, entry) {
|
||||
fprintf(cf, "\tMatchDevicePath \"");
|
||||
for (cur = group->values; *cur; cur++)
|
||||
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||
*cur);
|
||||
if (group->is_negated) fprintf(cf, "\tNoMatchDevicePath \"");
|
||||
else fprintf(cf, "\tMatchDevicePath \"");
|
||||
not_first = FALSE;
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
xf86printMatchPattern(cf, pattern, not_first);
|
||||
not_first = TRUE;
|
||||
}
|
||||
fprintf(cf, "\"\n");
|
||||
}
|
||||
xorg_list_for_each_entry(group, &ptr->match_os, entry) {
|
||||
fprintf(cf, "\tMatchOS \"");
|
||||
for (cur = group->values; *cur; cur++)
|
||||
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||
*cur);
|
||||
if (group->is_negated) fprintf(cf, "\tNoMatchOS \"");
|
||||
else fprintf(cf, "\tMatchOS \"");
|
||||
not_first = FALSE;
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
xf86printMatchPattern(cf, pattern, not_first);
|
||||
not_first = TRUE;
|
||||
}
|
||||
fprintf(cf, "\"\n");
|
||||
}
|
||||
xorg_list_for_each_entry(group, &ptr->match_pnpid, entry) {
|
||||
fprintf(cf, "\tMatchPnPID \"");
|
||||
for (cur = group->values; *cur; cur++)
|
||||
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||
*cur);
|
||||
if (group->is_negated) fprintf(cf, "\tNoMatchPnPID \"");
|
||||
else fprintf(cf, "\tMatchPnPID \"");
|
||||
not_first = FALSE;
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
xf86printMatchPattern(cf, pattern, not_first);
|
||||
not_first = TRUE;
|
||||
}
|
||||
fprintf(cf, "\"\n");
|
||||
}
|
||||
xorg_list_for_each_entry(group, &ptr->match_usbid, entry) {
|
||||
fprintf(cf, "\tMatchUSBID \"");
|
||||
for (cur = group->values; *cur; cur++)
|
||||
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||
*cur);
|
||||
if (group->is_negated) fprintf(cf, "\tNoMatchUSBID \"");
|
||||
else fprintf(cf, "\tMatchUSBID \"");
|
||||
not_first = FALSE;
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
xf86printMatchPattern(cf, pattern, not_first);
|
||||
not_first = TRUE;
|
||||
}
|
||||
fprintf(cf, "\"\n");
|
||||
}
|
||||
xorg_list_for_each_entry(group, &ptr->match_driver, entry) {
|
||||
fprintf(cf, "\tMatchDriver \"");
|
||||
for (cur = group->values; *cur; cur++)
|
||||
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||
*cur);
|
||||
if (group->is_negated) fprintf(cf, "\tNoMatchDriver \"");
|
||||
else fprintf(cf, "\tMatchDriver \"");
|
||||
not_first = FALSE;
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
xf86printMatchPattern(cf, pattern, not_first);
|
||||
not_first = TRUE;
|
||||
}
|
||||
fprintf(cf, "\"\n");
|
||||
}
|
||||
xorg_list_for_each_entry(group, &ptr->match_tag, entry) {
|
||||
fprintf(cf, "\tMatchTag \"");
|
||||
for (cur = group->values; *cur; cur++)
|
||||
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||
*cur);
|
||||
if (group->is_negated) fprintf(cf, "\tNoMatchTAG \"");
|
||||
else fprintf(cf, "\tMatchTAG \"");
|
||||
not_first = FALSE;
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
xf86printMatchPattern(cf, pattern, not_first);
|
||||
not_first = TRUE;
|
||||
}
|
||||
fprintf(cf, "\"\n");
|
||||
}
|
||||
xorg_list_for_each_entry(group, &ptr->match_layout, entry) {
|
||||
fprintf(cf, "\tMatchLayout \"");
|
||||
for (cur = group->values; *cur; cur++)
|
||||
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||
*cur);
|
||||
if (group->is_negated) fprintf(cf, "\tNoMatchLayout \"");
|
||||
else fprintf(cf, "\tMatchLayout \"");
|
||||
not_first = FALSE;
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
xf86printMatchPattern(cf, pattern, not_first);
|
||||
not_first = TRUE;
|
||||
}
|
||||
fprintf(cf, "\"\n");
|
||||
}
|
||||
|
||||
if (ptr->is_keyboard.set)
|
||||
fprintf(cf, "\tIsKeyboard \"%s\"\n",
|
||||
ptr->is_keyboard.val ? "yes" : "no");
|
||||
|
||||
@@ -66,23 +66,12 @@ xf86freeOutputClassList(XF86ConfOutputClassPtr ptr)
|
||||
|
||||
#define CLEANUP xf86freeOutputClassList
|
||||
|
||||
#define TOKEN_SEP "|"
|
||||
|
||||
static void
|
||||
add_group_entry(struct xorg_list *head, char **values)
|
||||
{
|
||||
xf86MatchGroup *group = calloc(1, sizeof(xf86MatchGroup));
|
||||
if (group) {
|
||||
group->values = values;
|
||||
xorg_list_add(&group->entry, head);
|
||||
}
|
||||
}
|
||||
|
||||
XF86ConfOutputClassPtr
|
||||
xf86parseOutputClassSection(void)
|
||||
{
|
||||
int has_ident = FALSE;
|
||||
int token;
|
||||
xf86MatchGroup *group;
|
||||
|
||||
parsePrologue(XF86ConfOutputClassPtr, XF86ConfOutputClassRec)
|
||||
|
||||
@@ -129,9 +118,12 @@ xf86parseOutputClassSection(void)
|
||||
case MATCH_DRIVER:
|
||||
if (xf86getSubToken(&(ptr->comment)) != XF86_TOKEN_STRING)
|
||||
Error(QUOTE_MSG, "MatchDriver");
|
||||
add_group_entry(&ptr->match_driver,
|
||||
xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
|
||||
free(xf86_lex_val.str);
|
||||
else {
|
||||
group = xf86createMatchGroup(xf86_lex_val.str, MATCH_EXACT, FALSE);
|
||||
if (group)
|
||||
xorg_list_add(&group->entry, &ptr->match_driver);
|
||||
free(xf86_lex_val.str);
|
||||
}
|
||||
break;
|
||||
case EOF_TOKEN:
|
||||
Error(UNEXPECTED_EOF_MSG);
|
||||
@@ -151,11 +143,13 @@ xf86parseOutputClassSection(void)
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void
|
||||
xf86printOutputClassSection(FILE * cf, XF86ConfOutputClassPtr ptr)
|
||||
{
|
||||
const xf86MatchGroup *group;
|
||||
char *const *cur;
|
||||
const xf86MatchPattern *pattern;
|
||||
Bool not_first;
|
||||
|
||||
while (ptr) {
|
||||
fprintf(cf, "Section \"OutputClass\"\n");
|
||||
@@ -168,9 +162,11 @@ xf86printOutputClassSection(FILE * cf, XF86ConfOutputClassPtr ptr)
|
||||
|
||||
xorg_list_for_each_entry(group, &ptr->match_driver, entry) {
|
||||
fprintf(cf, "\tMatchDriver \"");
|
||||
for (cur = group->values; *cur; cur++)
|
||||
fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
|
||||
*cur);
|
||||
not_first = FALSE;
|
||||
xorg_list_for_each_entry(pattern, &group->patterns, entry) {
|
||||
xf86printMatchPattern(cf, pattern, not_first);
|
||||
not_first = TRUE;
|
||||
}
|
||||
fprintf(cf, "\"\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -304,7 +304,6 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
struct xorg_list entry;
|
||||
char **values;
|
||||
struct xorg_list patterns;
|
||||
Bool is_negated;
|
||||
} xf86MatchGroup;
|
||||
|
||||
@@ -28,12 +28,12 @@ int xf86layoutAddInputDevices(XF86ConfigPtr config, XF86ConfLayoutPtr layout);
|
||||
static inline void xf86freeMatchGroup(xf86MatchGroup *group)
|
||||
{
|
||||
xorg_list_del(&group->entry);
|
||||
if (group->values) {
|
||||
for (char **list = group->values; *list; list++) {
|
||||
free(*list);
|
||||
*list = NULL;
|
||||
}
|
||||
group->values = NULL;
|
||||
xf86MatchPattern *pattern, *next_pattern;
|
||||
xorg_list_for_each_entry_safe(pattern, next_pattern, &group->patterns, entry) {
|
||||
xorg_list_del(&pattern->entry);
|
||||
if (pattern->str)
|
||||
free(pattern->str);
|
||||
free(pattern);
|
||||
}
|
||||
free(group);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user