summaryrefslogtreecommitdiff
path: root/app/xkbcomp/parseutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/xkbcomp/parseutils.c')
-rw-r--r--app/xkbcomp/parseutils.c748
1 files changed, 748 insertions, 0 deletions
diff --git a/app/xkbcomp/parseutils.c b/app/xkbcomp/parseutils.c
new file mode 100644
index 000000000..bae18f902
--- /dev/null
+++ b/app/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;
+}