summaryrefslogtreecommitdiff
path: root/parseutils.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:54 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:54 +0000
commit2af3aabf0e7eb1514d39b29a6b58fcd0d4de41d1 (patch)
tree93f90d2a90d9163a9b8930ae643dcabae310350f /parseutils.c
downloadxorg-app-xkbcomp-2af3aabf0e7eb1514d39b29a6b58fcd0d4de41d1.tar.gz
R6.6 is the Xorg base-lineXORG-MAIN
Diffstat (limited to 'parseutils.c')
-rw-r--r--parseutils.c966
1 files changed, 966 insertions, 0 deletions
diff --git a/parseutils.c b/parseutils.c
new file mode 100644
index 0000000..468d620
--- /dev/null
+++ b/parseutils.c
@@ -0,0 +1,966 @@
+/* $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.
+
+ ********************************************************/
+#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 *
+#if NeedFunctionPrototypes
+AppendStmt(ParseCommon *to,ParseCommon *append)
+#else
+AppendStmt(to,append)
+ ParseCommon * to;
+ ParseCommon * append;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+ExprCreate(unsigned op,unsigned type)
+#else
+ExprCreate(op,type)
+ unsigned op;
+ unsigned type;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+ExprCreateUnary(unsigned op,unsigned type,ExprDef *child)
+#else
+ExprCreateUnary(op,type,child)
+ unsigned op;
+ unsigned type;
+ ExprDef *child;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+ExprCreateBinary(unsigned op,ExprDef *left,ExprDef *right)
+#else
+ExprCreateBinary(op,left,right)
+ unsigned op;
+ ExprDef *left;
+ ExprDef *right;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+KeycodeCreate(char *name,ExprDef *value)
+#else
+KeycodeCreate(name,value)
+ char * name;
+ ExprDef * value;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+KeyAliasCreate(char *alias,char *real)
+#else
+KeyAliasCreate(alias,real)
+ char * alias;
+ char * real;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+VModCreate(Atom name,ExprDef *value)
+#else
+VModCreate(name,value)
+ Atom name;
+ ExprDef * value;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+VarCreate(ExprDef *name,ExprDef *value)
+#else
+VarCreate(name,value)
+ ExprDef * name;
+ ExprDef * value;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+BoolVarCreate(Atom nameToken,unsigned set)
+#else
+BoolVarCreate(nameToken,set)
+ Atom nameToken;
+ unsigned set;
+#endif
+{
+ExprDef *name,*value;
+
+ name= ExprCreate(ExprIdent,TypeUnknown);
+ name->value.str= nameToken;
+ value= ExprCreate(ExprValue,TypeBoolean);
+ value->value.uval= set;
+ return VarCreate(name,value);
+}
+
+InterpDef *
+#if NeedFunctionPrototypes
+InterpCreate(KeySym sym,ExprDef *match)
+#else
+InterpCreate(sym,match)
+ KeySym sym;
+ ExprDef * match;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+KeyTypeCreate(Atom name,VarDef *body)
+#else
+KeyTypeCreate(name,body)
+ Atom name;
+ VarDef * body;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+SymbolsCreate(char *keyName,ExprDef *symbols)
+#else
+SymbolsCreate(keyName,symbols)
+ char * keyName;
+ ExprDef * symbols;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+GroupCompatCreate(int group,ExprDef *val)
+#else
+GroupCompatCreate(group,val)
+ int group;
+ ExprDef * val;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+ModMapCreate(Atom modifier,ExprDef *keys)
+#else
+ModMapCreate(modifier,keys)
+ Atom modifier;
+ ExprDef * keys;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+IndicatorMapCreate(Atom name,VarDef *body)
+#else
+IndicatorMapCreate(name,body)
+ Atom name;
+ VarDef * body;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+IndicatorNameCreate(int ndx,ExprDef *name,Bool virtual)
+#else
+IndicatorNameCreate(ndx,name,virtual)
+ int ndx;
+ ExprDef * name;
+ Bool virtual;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+ActionCreate(Atom name,ExprDef *args)
+#else
+ActionCreate(name,args)
+ Atom name;
+ ExprDef *args;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+CreateKeysymList(KeySym sym)
+#else
+CreateKeysymList(sym)
+ KeySym sym;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+ShapeDeclCreate(Atom name,OutlineDef *outlines)
+#else
+ShapeDeclCreate(name,outlines)
+ Atom name;
+ OutlineDef * outlines;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+OutlineCreate(Atom field,ExprDef *points)
+#else
+OutlineCreate(field,points)
+ Atom field;
+ ExprDef * points;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+KeyDeclCreate(char *name,ExprDef *expr)
+#else
+KeyDeclCreate(name,expr)
+ char * name;
+ ExprDef * expr;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+KeyDeclMerge(KeyDef *into,KeyDef *from)
+#else
+KeyDeclMerge(into,from)
+ KeyDef * into;
+ KeyDef * from;
+#endif
+{
+ into->expr= (ExprDef *)AppendStmt(&into->expr->common,&from->expr->common);
+ from->expr= NULL;
+ uFree(from);
+ return into;
+}
+
+RowDef *
+#if NeedFunctionPrototypes
+RowDeclCreate(KeyDef * keys)
+#else
+RowDeclCreate(keys)
+ KeyDef * keys;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+SectionDeclCreate(Atom name,RowDef *rows)
+#else
+SectionDeclCreate(name,rows)
+ Atom name;
+ RowDef * rows;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+OverlayKeyCreate(char * under,char *over)
+#else
+OverlayKeyCreate(under,over)
+ char * under;
+ char * over;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+OverlayDeclCreate(Atom name,OverlayKeyDef *keys)
+#else
+OverlayDeclCreate(name,keys)
+ Atom name;
+ OverlayKeyDef * keys;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+DoodadCreate(unsigned type,Atom name,VarDef *body)
+#else
+DoodadCreate(type,name,body)
+ unsigned type;
+ Atom name;
+ VarDef * body;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+AppendKeysymList(ExprDef *list,KeySym sym)
+#else
+AppendKeysymList(list,sym)
+ ExprDef * list;
+ KeySym sym;
+#endif
+{
+ 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
+#if NeedFunctionPrototypes
+LookupKeysym(char *str,KeySym *sym_rtrn)
+#else
+LookupKeysym(str,sym_rtrn)
+ char *str;
+ KeySym *sym_rtrn;
+#endif
+{
+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 *
+#if NeedFunctionPrototypes
+IncludeCreate(char *str,unsigned merge)
+#else
+IncludeCreate(str,merge)
+ char * str;
+ unsigned merge;
+#endif
+{
+IncludeStmt * incl,*first;
+char * file,*map,*stmt,*tmp;
+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)) {
+ 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->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->path) uFree(first->path);
+ first->file= first->map= first->path= NULL;
+ uFree(first);
+ first= incl;
+ }
+ if (stmt)
+ uFree(stmt);
+ return NULL;
+}
+
+#ifdef DEBUG
+void
+#if NeedFunctionPrototypes
+PrintStmtAddrs(ParseCommon *stmt)
+#else
+PrintStmtAddrs(stmt)
+ ParseCommon * stmt;
+#endif
+{
+ 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
+#if NeedFunctionPrototypes
+CheckDefaultMap(XkbFile *maps)
+#else
+CheckDefaultMap(maps)
+XkbFile *maps;
+#endif
+{
+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;
+}
+
+_XFUNCPROTOBEGIN
+extern int yyparse(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+_XFUNCPROTOEND
+
+extern FILE * yyin;
+
+int
+#if NeedFunctionPrototypes
+XKBParseFile(FILE *file,XkbFile **pRtrn)
+#else
+XKBParseFile(file,pRtrn)
+FILE *file;
+XkbFile **pRtrn;
+#endif
+{
+ 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 *
+#if NeedFunctionPrototypes
+CreateXKBFile(int type,char *name,ParseCommon *defs,unsigned flags)
+#else
+CreateXKBFile(type,name,defs,flags)
+int type;
+char * name;
+ParseCommon * defs;
+unsigned flags;
+#endif
+{
+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
+#if NeedFunctionPrototypes
+StmtSetMerge(ParseCommon *stmt,unsigned merge)
+#else
+StmtSetMerge(stmt,merge)
+ ParseCommon * stmt;
+ unsigned merge;
+#endif
+{
+ if ((merge==MergeAltForm) && (stmt->stmtType!=StmtKeycodeDef)) {
+ yyerror("illegal use of 'alternate' merge mode");
+ merge= MergeDefault;
+ }
+ return merge;
+}