summaryrefslogtreecommitdiff
path: root/xkb/maprules.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:49:22 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:49:22 +0000
commitd568221710959cf7d783e6ff0fb80fb43a231124 (patch)
tree8d6f039393294c6ffac8533639afdebe5d68bfc1 /xkb/maprules.c
parent9508a382f8a9f241dab097d921b6d290c1c3a776 (diff)
Diffstat (limited to 'xkb/maprules.c')
-rw-r--r--xkb/maprules.c664
1 files changed, 487 insertions, 177 deletions
diff --git a/xkb/maprules.c b/xkb/maprules.c
index 559dc9c7f..8c5ce1a42 100644
--- a/xkb/maprules.c
+++ b/xkb/maprules.c
@@ -24,13 +24,11 @@
THE USE OR PERFORMANCE OF THIS SOFTWARE.
********************************************************/
+/* $XFree86: xc/lib/xkbfile/maprules.c,v 3.17 2002/11/26 01:43:25 dawes Exp $ */
#include <stdio.h>
#include <ctype.h>
-#ifndef X_NOT_STDC_ENV
#include <stdlib.h>
-#endif
-
#define X_INCLUDE_STRING_H
#define XOS_USE_NO_LOCKING
@@ -69,11 +67,13 @@
#endif
#ifdef DEBUG
-#define PR_DEBUG(s) fprintf(stderr,s)
-#define PR_DEBUG1(s,a) fprintf(stderr,s,a)
+#define PR_DEBUG(s) fprintf(stderr,s)
+#define PR_DEBUG1(s,a) fprintf(stderr,s,a)
+#define PR_DEBUG2(s,a,b) fprintf(stderr,s,a,b)
#else
#define PR_DEBUG(s)
#define PR_DEBUG1(s,a)
+#define PR_DEBUG2(s,a,b)
#endif
/***====================================================================***/
@@ -254,8 +254,12 @@ static char * cname[MAX_WORDS] = {
};
typedef struct _RemapSpec {
+ int number;
int num_remap;
- int remap[MAX_WORDS];
+ struct {
+ int word;
+ int index;
+ } remap[MAX_WORDS];
} RemapSpec;
typedef struct _FileSpec {
@@ -263,8 +267,49 @@ typedef struct _FileSpec {
struct _FileSpec * pending;
} FileSpec;
+typedef struct {
+ char * model;
+ char * layout[XkbNumKbdGroups+1];
+ char * variant[XkbNumKbdGroups+1];
+ char * options;
+} XkbRF_MultiDefsRec, *XkbRF_MultiDefsPtr;
+
+#define NDX_BUFF_SIZE 4
+
/***====================================================================***/
+static char*
+#if NeedFunctionPrototypes
+get_index(char *str, int *ndx)
+#else
+get_index(str, ndx)
+ char *str;
+ int *ndx;
+#endif
+{
+ char ndx_buf[NDX_BUFF_SIZE];
+ char *end;
+
+ if (*str != '[') {
+ *ndx = 0;
+ return str;
+ }
+ str++;
+ end = strchr(str, ']');
+ if (end == NULL) {
+ *ndx = -1;
+ return str - 1;
+ }
+ if ( (end - str) >= NDX_BUFF_SIZE) {
+ *ndx = -1;
+ return end + 1;
+ }
+ strncpy(ndx_buf, str, end - str);
+ ndx_buf[end - str] = '\0';
+ *ndx = atoi(ndx_buf);
+ return end + 1;
+}
+
static void
#if NeedFunctionPrototypes
SetUpRemap(InputLine *line,RemapSpec *remap)
@@ -275,16 +320,20 @@ SetUpRemap(line,remap)
#endif
{
char * tok,*str;
-unsigned present;
+unsigned present, l_ndx_present, v_ndx_present;
register int i;
+int len, ndx;
+_Xstrtokparams strtok_buf;
#ifdef DEBUG
Bool found;
#endif
-_Xstrtokparams strtok_buf;
- present= 0;
+
+ l_ndx_present = v_ndx_present = present= 0;
str= &line->line[1];
+ len = remap->number;
bzero((char *)remap,sizeof(RemapSpec));
+ remap->number = len;
while ((tok=_XStrtok(str," ",strtok_buf))!=NULL) {
#ifdef DEBUG
found= False;
@@ -293,17 +342,40 @@ _Xstrtokparams strtok_buf;
if (strcmp(tok,"=")==0)
continue;
for (i=0;i<MAX_WORDS;i++) {
- if (strcmp(cname[i],tok)==0) {
+ len = strlen(cname[i]);
+ if (strncmp(cname[i],tok,len)==0) {
+ if(strlen(tok) > len) {
+ char *end = get_index(tok+len, &ndx);
+ if ((i != LAYOUT && i != VARIANT) ||
+ *end != '\0' || ndx == -1)
+ break;
+ if (ndx < 1 || ndx > XkbNumKbdGroups) {
+ PR_DEBUG2("Illegal %s index: %d\n", cname[i], ndx);
+ PR_DEBUG1("Index must be in range 1..%d\n",
+ XkbNumKbdGroups);
+ break;
+ }
+ } else {
+ ndx = 0;
+ }
#ifdef DEBUG
found= True;
#endif
if (present&(1<<i)) {
- PR_DEBUG1("Component \"%s\" listed twice\n",tok);
- PR_DEBUG("Second definition ignored\n");
- break;
+ if ((i == LAYOUT && l_ndx_present&(1<<ndx)) ||
+ (i == VARIANT && v_ndx_present&(1<<ndx)) ) {
+ PR_DEBUG1("Component \"%s\" listed twice\n",tok);
+ PR_DEBUG("Second definition ignored\n");
+ break;
+ }
}
- present|= (1<<i);
- remap->remap[remap->num_remap++]= i;
+ present |= (1<<i);
+ if (i == LAYOUT)
+ l_ndx_present |= 1 << ndx;
+ if (i == VARIANT)
+ v_ndx_present |= 1 << ndx;
+ remap->remap[remap->num_remap].word= i;
+ remap->remap[remap->num_remap++].index= ndx;
break;
}
}
@@ -316,8 +388,8 @@ _Xstrtokparams strtok_buf;
if ((present&PART_MASK)==0) {
#ifdef DEBUG
unsigned mask= PART_MASK;
- fprintf(stderr,"Mapping needs at one of ");
- for (i=0;(i<MAX_WORDS)&mask;i++) {
+ fprintf(stderr,"Mapping needs at least one of ");
+ for (i=0; (i<MAX_WORDS); i++) {
if ((1L<<i)&mask) {
mask&= ~(1L<<i);
if (mask) fprintf(stderr,"\"%s,\" ",cname[i]);
@@ -349,6 +421,7 @@ _Xstrtokparams strtok_buf;
remap->num_remap= 0;
return;
}
+ remap->number++;
return;
}
@@ -386,23 +459,52 @@ static Bool
#if NeedFunctionPrototypes
CheckLine( InputLine * line,
RemapSpec * remap,
- XkbRF_RulePtr rule)
+ XkbRF_RulePtr rule,
+ XkbRF_GroupPtr group)
#else
-CheckLine(line,remap,rule)
+CheckLine(line,remap,rule,group)
InputLine * line;
RemapSpec * remap;
XkbRF_RulePtr rule;
+ XkbRF_GroupsPtr group;
#endif
{
char * str,*tok;
-register int nread;
+register int nread, i;
FileSpec tmp;
_Xstrtokparams strtok_buf;
+Bool append = False;
if (line->line[0]=='!') {
- SetUpRemap(line,remap);
- return False;
+ if (line->line[1] == '$' ||
+ (line->line[1] == ' ' && line->line[2] == '$')) {
+ char *gname = strchr(line->line, '$');
+ char *words = strchr(gname, ' ');
+ if(!words)
+ return False;
+ *words++ = '\0';
+ for (; *words; words++) {
+ if (*words != '=' && *words != ' ')
+ break;
+ }
+ if (*words == '\0')
+ return False;
+ group->name = _XkbDupString(gname);
+ group->words = _XkbDupString(words);
+ for (i = 1, words = group->words; *words; words++) {
+ if ( *words == ' ') {
+ *words++ = '\0';
+ i++;
+ }
+ }
+ group->number = i;
+ return True;
+ } else {
+ SetUpRemap(line,remap);
+ return False;
+ }
}
+
if (remap->num_remap==0) {
PR_DEBUG("Must have a mapping before first line of data\n");
PR_DEBUG("Illegal line of data ignored\n");
@@ -421,23 +523,24 @@ _Xstrtokparams strtok_buf;
PR_DEBUG1("Extra word \"%s\" ignored\n",tok);
continue;
}
- tmp.name[remap->remap[nread]]= tok;
+ tmp.name[remap->remap[nread].word]= tok;
+ if (*tok == '+' || *tok == '|')
+ append = True;
}
if (nread<remap->num_remap) {
- PR_DEBUG("Too few words on a line\n");
+ PR_DEBUG1("Too few words on a line: %s\n", line->line);
PR_DEBUG("line ignored\n");
return False;
}
- if ((tmp.name[MODEL]!=NULL)&&(strcmp(tmp.name[MODEL],"*")==0))
- tmp.name[MODEL]= NULL;
- if ((tmp.name[LAYOUT]!=NULL)&&(strcmp(tmp.name[LAYOUT],"*")==0))
- tmp.name[LAYOUT]= NULL;
- if ((tmp.name[VARIANT]!=NULL)&&(strcmp(tmp.name[VARIANT],"*")==0))
- tmp.name[VARIANT]= NULL;
rule->flags= 0;
+ rule->number = remap->number;
if (tmp.name[OPTION])
- rule->flags|= XkbRF_Delayed|XkbRF_Append;
+ rule->flags|= XkbRF_Option;
+ else if (append)
+ rule->flags|= XkbRF_Append;
+ else
+ rule->flags|= XkbRF_Normal;
rule->model= _XkbDupString(tmp.name[MODEL]);
rule->layout= _XkbDupString(tmp.name[LAYOUT]);
rule->variant= _XkbDupString(tmp.name[VARIANT]);
@@ -449,6 +552,16 @@ _Xstrtokparams strtok_buf;
rule->compat= _XkbDupString(tmp.name[COMPAT]);
rule->geometry= _XkbDupString(tmp.name[GEOMETRY]);
rule->keymap= _XkbDupString(tmp.name[KEYMAP]);
+
+ rule->layout_num = rule->variant_num = 0;
+ for (i = 0; i < nread; i++) {
+ if (remap->remap[i].index) {
+ if (remap->remap[i].word == LAYOUT)
+ rule->layout_num = remap->remap[i].index;
+ if (remap->remap[i].word == VARIANT)
+ rule->variant_num = remap->remap[i].index;
+ }
+ }
return True;
}
@@ -465,14 +578,127 @@ int len;
if ((!str1)||(!str2))
return str1;
- len= strlen(str1)+strlen(str2)+1;
+ len= strlen(str1)+strlen(str2)+1;
str1= _XkbTypedRealloc(str1,len,char);
if (str1)
strcat(str1,str2);
return str1;
}
-Bool
+static void
+#if NeedFunctionPrototypes
+squeeze_spaces(char *p1)
+#else
+squeeze_spaces(p1)
+ char *p1;
+#endif
+{
+ char *p2;
+ for (p2 = p1; *p2; p2++) {
+ *p1 = *p2;
+ if (*p1 != ' ') p1++;
+ }
+ *p1 = '\0';
+}
+
+static Bool
+#if NeedFunctionPrototypes
+MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
+#else
+MakeMultiDefs(mdefs, defs)
+ XkbRF_MultiDefsPtr mdefs
+ XkbRF_VarDefsPtr defs;
+#endif
+{
+
+ bzero((char *)mdefs,sizeof(XkbRF_MultiDefsRec));
+ mdefs->model = defs->model;
+ mdefs->options = _XkbDupString(defs->options);
+ if (mdefs->options) squeeze_spaces(mdefs->options);
+
+ if (defs->layout) {
+ if (!strchr(defs->layout, ',')) {
+ mdefs->layout[0] = defs->layout;
+ } else {
+ char *p;
+ int i;
+ mdefs->layout[1] = _XkbDupString(defs->layout);
+ if (mdefs->layout[1] == NULL)
+ return False;
+ squeeze_spaces(mdefs->layout[1]);
+ p = mdefs->layout[1];
+ for (i = 2; i <= XkbNumKbdGroups; i++) {
+ if ((p = strchr(p, ','))) {
+ *p++ = '\0';
+ mdefs->layout[i] = p;
+ } else {
+ break;
+ }
+ }
+ if (p && (p = strchr(p, ',')))
+ *p = '\0';
+ }
+ }
+
+ if (defs->variant) {
+ if (!strchr(defs->variant, ',')) {
+ mdefs->variant[0] = defs->variant;
+ } else {
+ char *p;
+ int i;
+ mdefs->variant[1] = _XkbDupString(defs->variant);
+ if (mdefs->variant[1] == NULL)
+ return False;
+ squeeze_spaces(mdefs->variant[1]);
+ p = mdefs->variant[1];
+ for (i = 2; i <= XkbNumKbdGroups; i++) {
+ if ((p = strchr(p, ','))) {
+ *p++ = '\0';
+ mdefs->variant[i] = p;
+ } else {
+ break;
+ }
+ }
+ if (p && (p = strchr(p, ',')))
+ *p = '\0';
+ }
+ }
+ return True;
+}
+
+static void
+#if NeedFunctionPrototypes
+FreeMultiDefs(XkbRF_MultiDefsPtr defs)
+#else
+FreeMultiDefs(defs)
+ XkbRF_MultiDefsPtr defs;
+#endif
+{
+ if (defs->options) _XkbFree(defs->options);
+ if (defs->layout[1]) _XkbFree(defs->layout[1]);
+ if (defs->variant[1]) _XkbFree(defs->variant[1]);
+}
+
+static void
+#if NeedFunctionPrototypes
+Apply(char *src, char **dst)
+#else
+Apply(src, dst)
+ char *src;
+ char *dst;
+#endif
+{
+ if (src) {
+ if (*src == '+' || *src == '!') {
+ *dst= _Concat(*dst, src);
+ } else {
+ if (*dst == NULL)
+ *dst= _XkbDupString(src);
+ }
+ }
+}
+
+static void
#if NeedFunctionPrototypes
XkbRF_ApplyRule( XkbRF_RulePtr rule,
XkbComponentNamesPtr names)
@@ -483,86 +709,129 @@ XkbRF_ApplyRule(rule,names)
#endif
{
rule->flags&= ~XkbRF_PendingMatch; /* clear the flag because it's applied */
- if ((rule->flags&XkbRF_Append)==0) {
- if ((names->keycodes==NULL)&&(rule->keycodes!=NULL))
- names->keycodes= _XkbDupString(rule->keycodes);
-
- if ((names->symbols==NULL)&&(rule->symbols!=NULL))
- names->symbols= _XkbDupString(rule->symbols);
-
- if ((names->types==NULL)&&(rule->types!=NULL))
- names->types= _XkbDupString(rule->types);
- if ((names->compat==NULL)&&(rule->compat!=NULL))
- names->compat= _XkbDupString(rule->compat);
-
- if ((names->geometry==NULL)&&(rule->geometry!=NULL))
- names->geometry= _XkbDupString(rule->geometry);
-
- if ((names->keymap==NULL)&&(rule->keymap!=NULL))
- names->keymap= _XkbDupString(rule->keymap);
- }
- else {
- if (rule->keycodes)
- names->keycodes= _Concat(names->keycodes,rule->keycodes);
- if (rule->symbols)
- names->symbols= _Concat(names->symbols,rule->symbols);
- if (rule->types)
- names->types= _Concat(names->types,rule->types);
- if (rule->compat)
- names->compat= _Concat(names->compat,rule->compat);
- if (rule->geometry)
- names->geometry= _Concat(names->geometry,rule->geometry);
- if (rule->keymap)
- names->keymap= _Concat(names->keymap,rule->keymap);
- }
- return (names->keycodes && names->symbols && names->types &&
- names->compat && names->geometry ) || names->keymap;
+ Apply(rule->keycodes, &names->keycodes);
+ Apply(rule->symbols, &names->symbols);
+ Apply(rule->types, &names->types);
+ Apply(rule->compat, &names->compat);
+ Apply(rule->geometry, &names->geometry);
+ Apply(rule->keymap, &names->keymap);
}
-#define CHECK_MATCH(r,d) ((((r)[0]=='?')&&((r)[1]=='\0'))||(strcmp(r,d)==0))
+static Bool
+#if NeedFunctionPrototypes
+CheckGroup( XkbRF_RulesPtr rules,
+ char * group_name,
+ char * name)
+#else
+XkbRF_CheckApplyRule(rules,group,name)
+ XkbRF_RulesPtr rules;
+ char * group_name;
+ char * name;
+#endif
+{
+ int i;
+ char *p;
+ XkbRF_GroupPtr group;
+
+ for (i = 0, group = rules->groups; i < rules->num_groups; i++, group++) {
+ if (! strcmp(group->name, group_name)) {
+ break;
+ }
+ }
+ if (i == rules->num_groups)
+ return False;
+ for (i = 0, p = group->words; i < group->number; i++, p += strlen(p)+1) {
+ if (! strcmp(p, name)) {
+ return True;
+ }
+ }
+ return False;
+}
-Bool
+static int
#if NeedFunctionPrototypes
XkbRF_CheckApplyRule( XkbRF_RulePtr rule,
- XkbRF_VarDefsPtr defs,
- XkbComponentNamesPtr names)
+ XkbRF_MultiDefsPtr mdefs,
+ XkbComponentNamesPtr names,
+ XkbRF_RulesPtr rules)
#else
-XkbRF_CheckApplyRule(rule,defs,names)
+XkbRF_CheckApplyRule(rule,mdefs,names)
XkbRF_RulePtr rule;
- XkbRF_VarDefsPtr defs;
+ XkbRF_MultiDefsPtr mdefs;
XkbComponentNamesPtr names;
+ XkbRF_RulesPtr rules;
#endif
{
- if (rule->model!=NULL) {
- if ((!defs->model)||(!CHECK_MATCH(rule->model,defs->model)))
- return False;
+ Bool pending = False;
+
+ if (rule->model != NULL) {
+ if(mdefs->model == NULL)
+ return 0;
+ if (strcmp(rule->model, "*") == 0) {
+ pending = True;
+ } else {
+ if (rule->model[0] == '$') {
+ if (!CheckGroup(rules, rule->model, mdefs->model))
+ return 0;
+ } else {
+ if (strcmp(rule->model, mdefs->model) != 0)
+ return 0;
+ }
+ }
}
- if (rule->layout!=NULL) {
- if ((!defs->layout)||(!CHECK_MATCH(rule->layout,defs->layout)))
- return False;
+ if (rule->option != NULL) {
+ if (mdefs->options == NULL)
+ return 0;
+ if ((!MatchOneOf(rule->option,mdefs->options)))
+ return 0;
}
- if (rule->variant!=NULL) {
- if ((!defs->variant)||(!CHECK_MATCH(rule->variant,defs->variant)))
- return False;
+
+ if (rule->layout != NULL) {
+ if(mdefs->layout[rule->layout_num] == NULL ||
+ *mdefs->layout[rule->layout_num] == '\0')
+ return 0;
+ if (strcmp(rule->layout, "*") == 0) {
+ pending = True;
+ } else {
+ if (rule->layout[0] == '$') {
+ if (!CheckGroup(rules, rule->layout,
+ mdefs->layout[rule->layout_num]))
+ return 0;
+ } else {
+ if (strcmp(rule->layout, mdefs->layout[rule->layout_num]) != 0)
+ return 0;
+ }
+ }
}
- if (rule->option!=NULL) {
- if ((!defs->options)||(!MatchOneOf(rule->option,defs->options)))
- return False;
+ if (rule->variant != NULL) {
+ if (mdefs->variant[rule->variant_num] == NULL ||
+ *mdefs->variant[rule->variant_num] == '\0')
+ return 0;
+ if (strcmp(rule->variant, "*") == 0) {
+ pending = True;
+ } else {
+ if (rule->variant[0] == '$') {
+ if (!CheckGroup(rules, rule->variant,
+ mdefs->variant[rule->variant_num]))
+ return 0;
+ } else {
+ if (strcmp(rule->variant,
+ mdefs->variant[rule->variant_num]) != 0)
+ return 0;
+ }
+ }
}
-
- if ((!rule->option)&&
- ((!rule->model)||(!rule->layout)||(!rule->variant))) {
- /* partial map -- partial maps are applied in the order they */
- /* appear, but all partial maps come before any options. */
- rule->flags|= XkbRF_PendingMatch;
- return False;
+ if (pending) {
+ rule->flags|= XkbRF_PendingMatch;
+ return rule->number;
}
/* exact match, apply it now */
- return XkbRF_ApplyRule(rule,names);
+ XkbRF_ApplyRule(rule,names);
+ return rule->number;
}
-void
+static void
#if NeedFunctionPrototypes
XkbRF_ClearPartialMatches(XkbRF_RulesPtr rules)
#else
@@ -578,7 +847,7 @@ XkbRF_RulePtr rule;
}
}
-Bool
+static void
#if NeedFunctionPrototypes
XkbRF_ApplyPartialMatches(XkbRF_RulesPtr rules,XkbComponentNamesPtr names)
#else
@@ -589,78 +858,57 @@ XkbRF_ApplyPartialMatches(rules,names)
{
int i;
XkbRF_RulePtr rule;
-Bool complete;
- complete= False;
- for (rule=rules->rules,i=0;(i<rules->num_rules)&&(!complete);i++,rule++) {
+ for (rule = rules->rules, i = 0; i < rules->num_rules; i++, rule++) {
if ((rule->flags&XkbRF_PendingMatch)==0)
continue;
- complete= XkbRF_ApplyRule(rule,names);
- }
- return complete;
-}
-
-void
-#if NeedFunctionPrototypes
-XkbRF_CheckApplyDelayedRules( XkbRF_RulesPtr rules,
- XkbRF_VarDefsPtr defs,
- XkbComponentNamesPtr names)
-#else
-XkbRF_CheckApplyDelayedRules(rules,defs,names)
- XkbRF_RulesPtr rules;
- XkbRF_VarDefsPtr defs;
- XkbComponentNamesPtr names;
-#endif
-{
-int i;
-XkbRF_RulePtr rule;
-
- for (rule=rules->rules,i=0;(i<rules->num_rules);i++,rule++) {
- if ((rule->flags&XkbRF_Delayed)==0)
- continue;
- XkbRF_CheckApplyRule(rule,defs,names);
+ XkbRF_ApplyRule(rule,names);
}
- return;
}
-Bool
+static void
#if NeedFunctionPrototypes
XkbRF_CheckApplyRules( XkbRF_RulesPtr rules,
- XkbRF_VarDefsPtr defs,
- XkbComponentNamesPtr names)
+ XkbRF_MultiDefsPtr mdefs,
+ XkbComponentNamesPtr names,
+ int flags)
#else
-XkbRF_CheckApplyRules(rules,defs,names)
+XkbRF_CheckApplyRules(rules, mdefs, names, flags)
XkbRF_RulesPtr rules;
- XkbRF_VarDefsPtr defs;
+ XkbRF_MultiDefsPtr mdefs;
XkbComponentNamesPtr names;
+ int flags;
#endif
{
int i;
XkbRF_RulePtr rule;
-Bool complete;
+int skip;
- complete= False;
- for (rule=rules->rules,i=0;(i<rules->num_rules)&&(!complete);i++,rule++) {
- if ((rule->flags&XkbRF_Delayed)!=0)
+ for (rule = rules->rules, i=0; i < rules->num_rules; rule++, i++) {
+ if ((rule->flags & flags) != flags)
continue;
- complete= XkbRF_CheckApplyRule(rule,defs,names);
+ skip = XkbRF_CheckApplyRule(rule, mdefs, names, rules);
+ if (skip && !(flags & XkbRF_Option)) {
+ for ( ;(i < rules->num_rules) && (rule->number == skip);
+ rule++, i++);
+ rule--; i--;
+ }
}
- return complete;
}
/***====================================================================***/
-char *
+static char *
#if NeedFunctionPrototypes
-XkbRF_SubstituteVars(char *name,XkbRF_VarDefsPtr defs)
+XkbRF_SubstituteVars(char *name, XkbRF_MultiDefsPtr mdefs)
#else
-XkbRF_SubstituteVars(name,defs)
+XkbRF_SubstituteVars(name, mdefs)
char * name;
- XkbRF_VarDefsPtr defs;
+ XkbRF_MultiDefsPtr mdefs;
#endif
{
-char *str,*outstr,*orig;
-int len;
+char *str, *outstr, *orig, *var;
+int len, ndx;
orig= name;
str= index(name,'%');
@@ -678,17 +926,22 @@ int len;
extra_len= 2;
str++;
}
-
- if ((str[1]=='l')&&defs->layout)
- len+= strlen(defs->layout)+extra_len;
- else if ((str[1]=='m')&&defs->model)
- len+= strlen(defs->model)+extra_len;
- else if ((str[1]=='v')&&defs->variant)
- len+= strlen(defs->variant)+extra_len;
- if ((pfx=='(')&&(str[2]==')')) {
+ var = str + 1;
+ str = get_index(var + 1, &ndx);
+ if (ndx == -1) {
+ str = index(str,'%');
+ continue;
+ }
+ if ((*var=='l') && mdefs->layout[ndx] && *mdefs->layout[ndx])
+ len+= strlen(mdefs->layout[ndx])+extra_len;
+ else if ((*var=='m')&&mdefs->model)
+ len+= strlen(mdefs->model)+extra_len;
+ else if ((*var=='v') && mdefs->variant[ndx] && *mdefs->variant[ndx])
+ len+= strlen(mdefs->variant[ndx])+extra_len;
+ if ((pfx=='(')&&(*str==')')) {
str++;
}
- str= index(&str[1],'%');
+ str= index(&str[0],'%');
}
name= (char *)_XkbAlloc(len+1);
str= orig;
@@ -708,26 +961,30 @@ int len;
}
else pfx= '\0';
- if ((str[0]=='l')&&(defs->layout)) {
+ var = str;
+ str = get_index(var + 1, &ndx);
+ if (ndx == -1) {
+ continue;
+ }
+ if ((*var=='l') && mdefs->layout[ndx] && *mdefs->layout[ndx]) {
if (pfx) *outstr++= pfx;
- strcpy(outstr,defs->layout);
- outstr+= strlen(defs->layout);
+ strcpy(outstr,mdefs->layout[ndx]);
+ outstr+= strlen(mdefs->layout[ndx]);
if (sfx) *outstr++= sfx;
}
- else if ((str[0]=='m')&&(defs->model)) {
+ else if ((*var=='m')&&(mdefs->model)) {
if (pfx) *outstr++= pfx;
- strcpy(outstr,defs->model);
- outstr+= strlen(defs->model);
+ strcpy(outstr,mdefs->model);
+ outstr+= strlen(mdefs->model);
if (sfx) *outstr++= sfx;
}
- else if ((str[0]=='v')&&(defs->variant)) {
+ else if ((*var=='v') && mdefs->variant[ndx] && *mdefs->variant[ndx]) {
if (pfx) *outstr++= pfx;
- strcpy(outstr,defs->variant);
- outstr+= strlen(defs->variant);
+ strcpy(outstr,mdefs->variant[ndx]);
+ outstr+= strlen(mdefs->variant[ndx]);
if (sfx) *outstr++= sfx;
}
- str++;
- if ((pfx=='(')&&(str[0]==')'))
+ if ((pfx=='(')&&(*str==')'))
str++;
}
else {
@@ -754,26 +1011,32 @@ XkbRF_GetComponents(rules,defs,names)
XkbComponentNamesPtr names;
#endif
{
-Bool complete;
+ XkbRF_MultiDefsRec mdefs;
+
+ MakeMultiDefs(&mdefs, defs);
bzero((char *)names,sizeof(XkbComponentNamesRec));
XkbRF_ClearPartialMatches(rules);
- complete= XkbRF_CheckApplyRules(rules,defs,names);
- if (!complete)
- complete= XkbRF_ApplyPartialMatches(rules,names);
- XkbRF_CheckApplyDelayedRules(rules,defs,names);
+ XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Normal);
+ XkbRF_ApplyPartialMatches(rules, names);
+ XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Append);
+ XkbRF_ApplyPartialMatches(rules, names);
+ XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Option);
+
if (names->keycodes)
- names->keycodes= XkbRF_SubstituteVars(names->keycodes,defs);
+ names->keycodes= XkbRF_SubstituteVars(names->keycodes, &mdefs);
if (names->symbols)
- names->symbols= XkbRF_SubstituteVars(names->symbols,defs);
+ names->symbols= XkbRF_SubstituteVars(names->symbols, &mdefs);
if (names->types)
- names->types= XkbRF_SubstituteVars(names->types,defs);
+ names->types= XkbRF_SubstituteVars(names->types, &mdefs);
if (names->compat)
- names->compat= XkbRF_SubstituteVars(names->compat,defs);
+ names->compat= XkbRF_SubstituteVars(names->compat, &mdefs);
if (names->geometry)
- names->geometry= XkbRF_SubstituteVars(names->geometry,defs);
+ names->geometry= XkbRF_SubstituteVars(names->geometry, &mdefs);
if (names->keymap)
- names->keymap= XkbRF_SubstituteVars(names->keymap,defs);
+ names->keymap= XkbRF_SubstituteVars(names->keymap, &mdefs);
+
+ FreeMultiDefs(&mdefs);
return (names->keycodes && names->symbols && names->types &&
names->compat && names->geometry ) || names->keymap;
}
@@ -807,6 +1070,33 @@ XkbRF_AddRule(rules)
return &rules->rules[rules->num_rules++];
}
+XkbRF_GroupPtr
+#if NeedFunctionPrototypes
+XkbRF_AddGroup(XkbRF_RulesPtr rules)
+#else
+XkbRF_AddGroup(rules)
+ XkbRF_RulesPtr rules;
+#endif
+{
+ if (rules->sz_groups<1) {
+ rules->sz_groups= 16;
+ rules->num_groups= 0;
+ rules->groups= _XkbTypedCalloc(rules->sz_groups,XkbRF_GroupRec);
+ }
+ else if (rules->num_groups >= rules->sz_groups) {
+ rules->sz_groups *= 2;
+ rules->groups= _XkbTypedRealloc(rules->groups,rules->sz_groups,
+ XkbRF_GroupRec);
+ }
+ if (!rules->groups) {
+ rules->sz_groups= rules->num_groups= 0;
+ return NULL;
+ }
+
+ bzero((char *)&rules->groups[rules->num_groups],sizeof(XkbRF_GroupRec));
+ return &rules->groups[rules->num_groups++];
+}
+
Bool
#if NeedFunctionPrototypes
XkbRF_LoadRules(FILE *file, XkbRF_RulesPtr rules)
@@ -819,16 +1109,25 @@ XkbRF_LoadRules(file,rules)
InputLine line;
RemapSpec remap;
XkbRF_RuleRec trule,*rule;
+XkbRF_GroupRec tgroup,*group;
if (!(rules && file))
return False;
bzero((char *)&remap,sizeof(RemapSpec));
+ bzero((char *)&tgroup,sizeof(XkbRF_GroupRec));
InitInputLine(&line);
while (GetInputLine(file,&line,True)) {
- if (CheckLine(&line,&remap,&trule)) {
- if ((rule= XkbRF_AddRule(rules))!=NULL) {
- *rule= trule;
- bzero((char *)&trule,sizeof(XkbRF_RuleRec));
+ if (CheckLine(&line,&remap,&trule,&tgroup)) {
+ if (tgroup.number) {
+ if ((group= XkbRF_AddGroup(rules))!=NULL) {
+ *group= tgroup;
+ bzero((char *)&tgroup,sizeof(XkbRF_GroupRec));
+ }
+ } else {
+ if ((rule= XkbRF_AddRule(rules))!=NULL) {
+ *rule= trule;
+ bzero((char *)&trule,sizeof(XkbRF_RuleRec));
+ }
}
}
line.num_line= 0;
@@ -976,7 +1275,7 @@ XkbRF_LoadDescriptions(file,rules)
InputLine line;
XkbRF_VarDescRec tmp;
char *tok;
-int len,headingtype,extra_ndx;
+int len,headingtype,extra_ndx = 0;
bzero((char *)&tmp, sizeof(XkbRF_VarDescRec));
headingtype = HEAD_NONE;
@@ -1200,6 +1499,7 @@ XkbRF_Free(rules,freeRules)
{
int i;
XkbRF_RulePtr rule;
+XkbRF_GroupPtr group;
if (!rules)
return;
@@ -1233,6 +1533,16 @@ XkbRF_RulePtr rule;
rules->num_rules= rules->sz_rules= 0;
rules->rules= NULL;
}
+
+ if (rules->groups) {
+ for (i=0, group=rules->groups;i<rules->num_groups;i++,group++) {
+ if (group->name) _XkbFree(group->name);
+ if (group->words) _XkbFree(group->words);
+ }
+ _XkbFree(rules->groups);
+ rules->num_groups= 0;
+ rules->groups= NULL;
+ }
if (freeRules)
_XkbFree(rules);
return;
@@ -1246,7 +1556,7 @@ XkbRF_GetNamesProp(Display *dpy,char **rf_rtrn,XkbRF_VarDefsPtr vd_rtrn)
#else
XkbRF_GetNamesProp(dpy,rf_rtrn,vd_rtrn)
Display * dpy;
- char ** rf_rtrn;
+ char ** rf_rtrn;
XkbRF_VarDefsPtr vd_rtrn;
#endif
{