diff options
Diffstat (limited to 'xkbcomp/parseutils.c')
-rw-r--r-- | xkbcomp/parseutils.c | 748 |
1 files changed, 748 insertions, 0 deletions
diff --git a/xkbcomp/parseutils.c b/xkbcomp/parseutils.c new file mode 100644 index 000000000..bae18f902 --- /dev/null +++ b/xkbcomp/parseutils.c @@ -0,0 +1,748 @@ +/* $Xorg: parseutils.c,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH + THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ********************************************************/ +/* $XFree86$ */ + +#define DEBUG_VAR_NOT_LOCAL +#define DEBUG_VAR parseDebug +#include "parseutils.h" +#include "xkbpath.h" +#include <X11/keysym.h> +#include <X11/extensions/XKBgeom.h> +#include <X11/Xalloca.h> + +XkbFile *rtrnValue; + +ParseCommon * +AppendStmt(ParseCommon *to,ParseCommon *append) +{ +ParseCommon *start= to; + + if (append==NULL) + return to; + while ((to!=NULL) && (to->next!=NULL)) { + to= to->next; + } + if (to) { + to->next= append; + return start; + } + return append; +} + +ExprDef * +ExprCreate(unsigned op,unsigned type) +{ +ExprDef *expr; + expr= uTypedAlloc(ExprDef); + if (expr) { + expr->common.stmtType= StmtExpr; + expr->common.next= NULL; + expr->op= op; + expr->type= type; + } + else { + FATAL("Couldn't allocate expression in parser\n"); + /* NOTREACHED */ + } + return expr; +} + +ExprDef * +ExprCreateUnary(unsigned op,unsigned type,ExprDef *child) +{ +ExprDef *expr; + expr= uTypedAlloc(ExprDef); + if (expr) { + expr->common.stmtType= StmtExpr; + expr->common.next= NULL; + expr->op= op; + expr->type= type; + expr->value.child= child; + } + else { + FATAL("Couldn't allocate expression in parser\n"); + /* NOTREACHED */ + } + return expr; +} + +ExprDef * +ExprCreateBinary(unsigned op,ExprDef *left,ExprDef *right) +{ +ExprDef *expr; + expr= uTypedAlloc(ExprDef); + if (expr) { + expr->common.stmtType= StmtExpr; + expr->common.next= NULL; + expr->op= op; + if ((op==OpAssign)||(left->type==TypeUnknown)) + expr->type= right->type; + else if ((left->type==right->type)||(right->type==TypeUnknown)) + expr->type= left->type; + else expr->type= TypeUnknown; + expr->value.binary.left= left; + expr->value.binary.right= right; + } + else { + FATAL("Couldn't allocate expression in parser\n"); + /* NOTREACHED */ + } + return expr; +} + +KeycodeDef * +KeycodeCreate(char *name,ExprDef *value) +{ +KeycodeDef *def; + + def= uTypedAlloc(KeycodeDef); + if (def) { + def->common.stmtType= StmtKeycodeDef; + def->common.next= NULL; + strncpy(def->name,name,XkbKeyNameLength); + def->name[XkbKeyNameLength]= '\0'; + def->value= value; + } + else { + FATAL("Couldn't allocate key name definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +KeyAliasDef * +KeyAliasCreate(char *alias,char *real) +{ +KeyAliasDef *def; + + def= uTypedAlloc(KeyAliasDef); + if (def) { + def->common.stmtType= StmtKeyAliasDef; + def->common.next= NULL; + strncpy(def->alias,alias,XkbKeyNameLength); + def->alias[XkbKeyNameLength]= '\0'; + strncpy(def->real,real,XkbKeyNameLength); + def->real[XkbKeyNameLength]= '\0'; + } + else { + FATAL("Couldn't allocate key alias definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +VModDef * +VModCreate(Atom name,ExprDef *value) +{ +VModDef *def; + def= uTypedAlloc(VModDef); + if (def) { + def->common.stmtType= StmtVModDef; + def->common.next= NULL; + def->name= name; + def->value= value; + } + else { + FATAL("Couldn't allocate variable definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +VarDef * +VarCreate(ExprDef *name,ExprDef *value) +{ +VarDef *def; + def= uTypedAlloc(VarDef); + if (def) { + def->common.stmtType= StmtVarDef; + def->common.next= NULL; + def->name= name; + def->value= value; + } + else { + FATAL("Couldn't allocate variable definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +VarDef * +BoolVarCreate(Atom nameToken,unsigned set) +{ +ExprDef *name,*value; + + name= ExprCreate(ExprIdent,TypeUnknown); + name->value.str= nameToken; + value= ExprCreate(ExprValue,TypeBoolean); + value->value.uval= set; + return VarCreate(name,value); +} + +InterpDef * +InterpCreate(KeySym sym,ExprDef *match) +{ +InterpDef *def; + + def= uTypedAlloc(InterpDef); + if (def) { + def->common.stmtType= StmtInterpDef; + def->common.next= NULL; + def->sym= sym; + def->match= match; + } + else { + FATAL("Couldn't allocate interp definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +KeyTypeDef * +KeyTypeCreate(Atom name,VarDef *body) +{ +KeyTypeDef *def; + + def= uTypedAlloc(KeyTypeDef); + if (def) { + def->common.stmtType= StmtKeyTypeDef; + def->common.next= NULL; + def->merge= MergeDefault; + def->name= name; + def->body= body; + } + else { + FATAL("Couldn't allocate key type definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +SymbolsDef * +SymbolsCreate(char *keyName,ExprDef *symbols) +{ +SymbolsDef *def; + + def= uTypedAlloc(SymbolsDef); + if (def) { + def->common.stmtType= StmtSymbolsDef; + def->common.next= NULL; + def->merge= MergeDefault; + bzero(def->keyName,5); + strncpy(def->keyName,keyName,4); + def->symbols= symbols; + } + else { + FATAL("Couldn't allocate symbols definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +GroupCompatDef * +GroupCompatCreate(int group,ExprDef *val) +{ +GroupCompatDef *def; + + def= uTypedAlloc(GroupCompatDef); + if (def) { + def->common.stmtType= StmtGroupCompatDef; + def->common.next= NULL; + def->merge= MergeDefault; + def->group= group; + def->def= val; + } + else { + FATAL("Couldn't allocate group compat definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +ModMapDef * +ModMapCreate(Atom modifier,ExprDef *keys) +{ +ModMapDef *def; + + def= uTypedAlloc(ModMapDef); + if (def) { + def->common.stmtType= StmtModMapDef; + def->common.next= NULL; + def->merge= MergeDefault; + def->modifier= modifier; + def->keys= keys; + } + else { + FATAL("Couldn't allocate mod mask definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +IndicatorMapDef * +IndicatorMapCreate(Atom name,VarDef *body) +{ +IndicatorMapDef *def; + + def= uTypedAlloc(IndicatorMapDef); + if (def) { + def->common.stmtType= StmtIndicatorMapDef; + def->common.next= NULL; + def->merge= MergeDefault; + def->name= name; + def->body= body; + } + else { + FATAL("Couldn't allocate indicator map definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +IndicatorNameDef * +IndicatorNameCreate(int ndx,ExprDef *name,Bool virtual) +{ +IndicatorNameDef *def; + + def= uTypedAlloc(IndicatorNameDef); + if (def) { + def->common.stmtType= StmtIndicatorNameDef; + def->common.next= NULL; + def->merge= MergeDefault; + def->ndx= ndx; + def->name= name; + def->virtual= virtual; + } + else { + FATAL("Couldn't allocate indicator index definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +ExprDef * +ActionCreate(Atom name,ExprDef *args) +{ +ExprDef *act; + + act= uTypedAlloc(ExprDef); + if (act) { + act->common.stmtType= StmtExpr; + act->common.next= NULL; + act->op= ExprActionDecl; + act->value.action.name= name; + act->value.action.args= args; + return act; + } + FATAL("Couldn't allocate ActionDef in parser\n"); + return NULL; +} + +ExprDef * +CreateKeysymList(KeySym sym) +{ +ExprDef *def; + + def= ExprCreate(ExprKeysymList,TypeSymbols); + if (def) { + def->value.list.nSyms= 1; + def->value.list.szSyms= 2; + def->value.list.syms= uTypedCalloc(2,KeySym); + if (def->value.list.syms!=NULL) { + def->value.list.syms[0]= sym; + return def; + } + } + FATAL("Couldn't allocate expression for keysym list in parser\n"); + return NULL; +} + +ShapeDef * +ShapeDeclCreate(Atom name,OutlineDef *outlines) +{ +ShapeDef * shape; +OutlineDef * ol; + + shape= uTypedAlloc(ShapeDef); + if (shape!=NULL) { + bzero(shape,sizeof(ShapeDef)); + shape->common.stmtType= StmtShapeDef; + shape->common.next= NULL; + shape->merge= MergeDefault; + shape->name= name; + shape->nOutlines= 0; + shape->outlines= outlines; + for (ol=outlines;ol!=NULL;ol= (OutlineDef *)ol->common.next) { + if (ol->nPoints>0) + shape->nOutlines++; + } + } + return shape; +} + +OutlineDef * +OutlineCreate(Atom field,ExprDef *points) +{ +OutlineDef * outline; +ExprDef * pt; + + outline= uTypedAlloc(OutlineDef); + if (outline!=NULL) { + bzero(outline,sizeof(OutlineDef)); + outline->common.stmtType= StmtOutlineDef; + outline->common.next= NULL; + outline->field= field; + outline->nPoints= 0; + if (points->op==ExprCoord) { + for (pt=points;pt!=NULL;pt= (ExprDef *)pt->common.next) { + outline->nPoints++; + } + } + outline->points= points; + } + return outline; +} + +KeyDef * +KeyDeclCreate(char *name,ExprDef *expr) +{ +KeyDef * key; + + key= uTypedAlloc(KeyDef); + if (key!=NULL) { + bzero(key,sizeof(KeyDef)); + key->common.stmtType= StmtKeyDef; + key->common.next= NULL; + if (name) key->name= name; + else key->expr= expr; + } + return key; +} + +KeyDef * +KeyDeclMerge(KeyDef *into,KeyDef *from) +{ + into->expr= (ExprDef *)AppendStmt(&into->expr->common,&from->expr->common); + from->expr= NULL; + uFree(from); + return into; +} + +RowDef * +RowDeclCreate(KeyDef * keys) +{ +RowDef * row; +KeyDef * key; + + row= uTypedAlloc(RowDef); + if (row!=NULL) { + bzero(row,sizeof(RowDef)); + row->common.stmtType= StmtRowDef; + row->common.next= NULL; + row->nKeys= 0; + row->keys= keys; + for (key=keys;key!=NULL;key=(KeyDef *)key->common.next) { + if (key->common.stmtType==StmtKeyDef) + row->nKeys++; + } + } + return row; +} + +SectionDef * +SectionDeclCreate(Atom name,RowDef *rows) +{ +SectionDef * section; +RowDef * row; + + section= uTypedAlloc(SectionDef); + if (section!=NULL) { + bzero(section,sizeof(SectionDef)); + section->common.stmtType= StmtSectionDef; + section->common.next= NULL; + section->name= name; + section->nRows= 0; + section->rows= rows; + for (row=rows;row!=NULL;row=(RowDef *)row->common.next) { + if (row->common.stmtType==StmtRowDef) + section->nRows++; + } + } + return section; +} + +OverlayKeyDef * +OverlayKeyCreate(char * under,char *over) +{ +OverlayKeyDef * key; + + key= uTypedAlloc(OverlayKeyDef); + if (key!=NULL) { + bzero(key,sizeof(OverlayKeyDef)); + key->common.stmtType= StmtOverlayKeyDef; + strncpy(key->over,over,XkbKeyNameLength); + strncpy(key->under,under,XkbKeyNameLength); + if (over) uFree(over); + if (under) uFree(under); + } + return key; +} + +OverlayDef * +OverlayDeclCreate(Atom name,OverlayKeyDef *keys) +{ +OverlayDef * ol; +OverlayKeyDef * key; + + ol= uTypedAlloc(OverlayDef); + if (ol!=NULL) { + bzero(ol,sizeof(OverlayDef)); + ol->common.stmtType= StmtOverlayDef; + ol->name= name; + ol->keys= keys; + for (key=keys;key!=NULL;key=(OverlayKeyDef *)key->common.next) { + ol->nKeys++; + } + } + return ol; +} + +DoodadDef * +DoodadCreate(unsigned type,Atom name,VarDef *body) +{ +DoodadDef * doodad; + + doodad= uTypedAlloc(DoodadDef); + if (doodad!=NULL) { + bzero(doodad,sizeof(DoodadDef)); + doodad->common.stmtType= StmtDoodadDef; + doodad->common.next= NULL; + doodad->type= type; + doodad->name= name; + doodad->body= body; + } + return doodad; +} + +ExprDef * +AppendKeysymList(ExprDef *list,KeySym sym) +{ + if (list->value.list.nSyms>=list->value.list.szSyms) { + list->value.list.szSyms*=2; + list->value.list.syms= uTypedRecalloc(list->value.list.syms, + list->value.list.nSyms, + list->value.list.szSyms, + KeySym); + if (list->value.list.syms==NULL) { + FATAL("Couldn't resize list of symbols for append\n"); + return NULL; + } + } + list->value.list.syms[list->value.list.nSyms++]= sym; + return list; +} + +int +LookupKeysym(char *str,KeySym *sym_rtrn) +{ +KeySym sym; + + if ((!str)||(uStrCaseCmp(str,"any")==0)||(uStrCaseCmp(str,"nosymbol")==0)) { + *sym_rtrn= NoSymbol; + return 1; + } + else if ((uStrCaseCmp(str,"none")==0)||(uStrCaseCmp(str,"voidsymbol")==0)) { + *sym_rtrn= XK_VoidSymbol; + return 1; + } + sym= XStringToKeysym(str); + if (sym!=NoSymbol) { + *sym_rtrn= sym; + return 1; + } + return 0; +} + +IncludeStmt * +IncludeCreate(char *str,unsigned merge) +{ +IncludeStmt * incl,*first; +char * file,*map,*stmt,*tmp, *extra_data; +char nextop; +Bool haveSelf; + + haveSelf= False; + incl= first= NULL; + file= map= NULL; + tmp= str; + stmt= uStringDup(str); + while ((tmp)&&(*tmp)) { + if (XkbParseIncludeMap(&tmp,&file,&map,&nextop,&extra_data)) { + if ((file==NULL)&&(map==NULL)) { + if (haveSelf) + goto BAIL; + haveSelf= True; + } + if (first==NULL) + first= incl= uTypedAlloc(IncludeStmt); + else { + incl->next= uTypedAlloc(IncludeStmt); + incl= incl->next; + } + if (incl) { + incl->common.stmtType= StmtInclude; + incl->common.next= NULL; + incl->merge= merge; + incl->stmt= NULL; + incl->file= file; + incl->map= map; + incl->modifier= extra_data; + incl->path= NULL; + incl->next= NULL; + } + else { + WSGO("Allocation failure in IncludeCreate\n"); + ACTION("Using only part of the include\n"); + break; + } + if (nextop=='|') merge= MergeAugment; + else merge= MergeOverride; + } + else { + goto BAIL; + } + } + if (first) first->stmt= stmt; + else if (stmt) uFree(stmt); + return first; +BAIL: + ERROR1("Illegal include statement \"%s\"\n",stmt); + ACTION("Ignored\n"); + while (first) { + incl= first->next; + if (first->file) uFree(first->file); + if (first->map) uFree(first->map); + if (first->modifier) uFree(first->modifier); + if (first->path) uFree(first->path); + first->file= first->map= first->path= NULL; + uFree(first); + first= incl; + } + if (stmt) + uFree(stmt); + return NULL; +} + +#ifdef DEBUG +void +PrintStmtAddrs(ParseCommon *stmt) +{ + fprintf(stderr,"0x%x",stmt); + if (stmt) { + do { + fprintf(stderr,"->0x%x",stmt->next); + stmt= stmt->next; + } while (stmt); + } + fprintf(stderr,"\n"); +} +#endif + +static void +CheckDefaultMap(XkbFile *maps) +{ +XkbFile * dflt,*tmp; + + dflt= NULL; + for (tmp=maps,dflt=NULL;tmp!=NULL;tmp=(XkbFile *)tmp->common.next) { + if (tmp->flags&XkbLC_Default) { + if (dflt==NULL) + dflt= tmp; + else { + if (warningLevel>2) { + WARN1("Multiple default components in %s\n", + (scanFile?scanFile:"(unknown)")); + ACTION2("Using %s, ignoring %s\n", + (dflt->name?dflt->name:"(first)"), + (tmp->name?tmp->name:"(subsequent)")); + } + tmp->flags&= (~XkbLC_Default); + } + } + } + return; +} + +int +XKBParseFile(FILE *file,XkbFile **pRtrn) +{ + if (file) { + yyin= file; + rtrnValue= NULL; + if (yyparse()==0) { + *pRtrn= rtrnValue; + CheckDefaultMap(rtrnValue); + rtrnValue= NULL; + return 1; + } + *pRtrn= NULL; + return 0; + } + *pRtrn= NULL; + return 1; +} + +XkbFile * +CreateXKBFile(int type,char *name,ParseCommon *defs,unsigned flags) +{ +XkbFile * file; +static int fileID; + + file= uTypedAlloc(XkbFile); + if (file) { + XkbEnsureSafeMapName(name); + bzero(file,sizeof(XkbFile)); + file->type= type; + file->topName= uStringDup(name); + file->name= name; + file->defs= defs; + file->id= fileID++; + file->compiled= False; + file->flags= flags; + } + return file; +} + +unsigned +StmtSetMerge(ParseCommon *stmt,unsigned merge) +{ + if ((merge==MergeAltForm) && (stmt->stmtType!=StmtKeycodeDef)) { + yyerror("illegal use of 'alternate' merge mode"); + merge= MergeDefault; + } + return merge; +} |