diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:49:22 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:49:22 +0000 |
commit | d568221710959cf7d783e6ff0fb80fb43a231124 (patch) | |
tree | 8d6f039393294c6ffac8533639afdebe5d68bfc1 /xkb/maprules.c | |
parent | 9508a382f8a9f241dab097d921b6d290c1c3a776 (diff) |
XFree86 4.3.0.1xf86-4_3_0_1PRE_xf86-4_3_0_1
Diffstat (limited to 'xkb/maprules.c')
-rw-r--r-- | xkb/maprules.c | 664 |
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 { |