2009-03-27 07:55:32 -06:00
|
|
|
/************************************************************
|
|
|
|
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
|
2009-04-04 10:19:51 -06:00
|
|
|
documentation, and that the name of Silicon Graphics not be
|
|
|
|
used in advertising or publicity pertaining to distribution
|
2009-03-27 07:55:32 -06:00
|
|
|
of the software without specific prior written permission.
|
2009-04-04 10:19:51 -06:00
|
|
|
Silicon Graphics makes no representation about the suitability
|
2009-03-27 07:55:32 -06:00
|
|
|
of this software for any purpose. It is provided "as is"
|
|
|
|
without any express or implied warranty.
|
2009-04-04 10:19:51 -06:00
|
|
|
|
|
|
|
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
|
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
2009-03-27 07:55:32 -06:00
|
|
|
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
2009-04-04 10:19:51 -06:00
|
|
|
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
|
2009-03-27 07:55:32 -06:00
|
|
|
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
|
|
|
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
|
|
|
********************************************************/
|
|
|
|
|
|
|
|
#include "parseutils.h"
|
2009-04-08 08:46:25 -06:00
|
|
|
#include "xkbmisc.h"
|
2009-03-27 07:55:32 -06:00
|
|
|
#include "xkbpath.h"
|
2012-03-01 12:20:45 -07:00
|
|
|
#include "xkbparse.h"
|
2009-03-27 07:55:32 -06:00
|
|
|
#include <X11/keysym.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 *
|
2012-02-15 12:39:33 -07:00
|
|
|
KeycodeCreate(char *name, unsigned long value)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
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 *
|
2012-03-09 12:09:25 -07:00
|
|
|
VModCreate(xkb_atom_t name, ExprDef * value)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
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 *
|
2012-03-09 12:09:25 -07:00
|
|
|
BoolVarCreate(xkb_atom_t nameToken, unsigned set)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
ExprDef *name, *value;
|
|
|
|
|
|
|
|
name = ExprCreate(ExprIdent, TypeUnknown);
|
|
|
|
name->value.str = nameToken;
|
|
|
|
value = ExprCreate(ExprValue, TypeBoolean);
|
|
|
|
value->value.uval = set;
|
|
|
|
return VarCreate(name, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
InterpDef *
|
2010-06-21 07:27:58 -06:00
|
|
|
InterpCreate(char *sym, ExprDef * match)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
InterpDef *def;
|
|
|
|
|
|
|
|
def = uTypedAlloc(InterpDef);
|
|
|
|
if (def)
|
|
|
|
{
|
|
|
|
def->common.stmtType = StmtInterpDef;
|
|
|
|
def->common.next = NULL;
|
2012-02-15 17:22:11 -07:00
|
|
|
def->sym = sym;
|
2009-03-27 07:55:32 -06:00
|
|
|
def->match = match;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FATAL("Couldn't allocate interp definition in parser\n");
|
|
|
|
/* NOTREACHED */
|
|
|
|
}
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
KeyTypeDef *
|
2012-03-09 12:09:25 -07:00
|
|
|
KeyTypeCreate(xkb_atom_t name, VarDef * body)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
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;
|
2012-02-29 11:50:17 -07:00
|
|
|
memset(def->keyName, 0, 5);
|
2009-03-27 07:55:32 -06:00
|
|
|
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 *
|
2010-06-28 04:50:12 -06:00
|
|
|
ModMapCreate(uint32_t modifier, ExprDef * keys)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
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 *
|
2012-03-09 12:09:25 -07:00
|
|
|
IndicatorMapCreate(xkb_atom_t name, VarDef * body)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
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 *
|
2012-03-09 12:09:25 -07:00
|
|
|
ActionCreate(xkb_atom_t name, ExprDef * args)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
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 *
|
2010-06-15 12:38:16 -06:00
|
|
|
CreateKeysymList(char *sym)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
ExprDef *def;
|
|
|
|
|
|
|
|
def = ExprCreate(ExprKeysymList, TypeSymbols);
|
|
|
|
if (def)
|
|
|
|
{
|
|
|
|
def->value.list.nSyms = 1;
|
2010-06-15 12:38:16 -06:00
|
|
|
def->value.list.szSyms = 4;
|
|
|
|
def->value.list.syms = uTypedCalloc(4, char *);
|
2009-03-27 07:55:32 -06:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
ExprDef *
|
2010-06-15 12:38:16 -06:00
|
|
|
AppendKeysymList(ExprDef * list, char *sym)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
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,
|
2010-06-15 12:38:16 -06:00
|
|
|
char *);
|
2009-03-27 07:55:32 -06:00
|
|
|
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
|
2012-03-09 12:03:59 -07:00
|
|
|
LookupKeysym(char *str, xkb_keysym_t * sym_rtrn)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
2012-03-09 12:03:59 -07:00
|
|
|
xkb_keysym_t sym;
|
2009-03-27 07:55:32 -06:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2010-07-02 09:50:01 -06:00
|
|
|
sym = xkb_string_to_keysym(str);
|
2009-03-27 07:55:32 -06:00
|
|
|
if (sym != NoSymbol)
|
|
|
|
{
|
|
|
|
*sym_rtrn = sym;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-03-02 05:49:36 -07:00
|
|
|
static void
|
|
|
|
FreeInclude(IncludeStmt *incl);
|
|
|
|
|
2009-03-27 07:55:32 -06:00
|
|
|
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;
|
2009-04-05 21:27:35 -06:00
|
|
|
stmt = _XkbDupString(str);
|
2009-03-27 07:55:32 -06:00
|
|
|
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;
|
2012-02-29 10:56:39 -07:00
|
|
|
else
|
2010-06-28 04:58:01 -06:00
|
|
|
free(stmt);
|
2009-03-27 07:55:32 -06:00
|
|
|
return first;
|
2012-03-02 05:49:36 -07:00
|
|
|
|
|
|
|
BAIL:
|
2009-03-31 08:21:20 -06:00
|
|
|
ERROR("Illegal include statement \"%s\"\n", stmt);
|
2009-03-27 07:55:32 -06:00
|
|
|
ACTION("Ignored\n");
|
2012-03-02 05:49:36 -07:00
|
|
|
FreeInclude(first);
|
2012-02-29 10:56:39 -07:00
|
|
|
free(stmt);
|
2009-03-27 07:55:32 -06:00
|
|
|
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
|
|
|
|
|
2010-10-19 19:57:59 -06:00
|
|
|
void
|
2009-03-27 07:55:32 -06:00
|
|
|
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)
|
|
|
|
{
|
2009-03-31 08:21:20 -06:00
|
|
|
WARN("Multiple default components in %s\n",
|
2009-03-27 07:55:32 -06:00
|
|
|
(scanFile ? scanFile : "(unknown)"));
|
2009-03-31 08:21:20 -06:00
|
|
|
ACTION("Using %s, ignoring %s\n",
|
2009-03-27 07:55:32 -06:00
|
|
|
(dflt->name ? dflt->name : "(first)"),
|
|
|
|
(tmp->name ? tmp->name : "(subsequent)"));
|
|
|
|
}
|
|
|
|
tmp->flags &= (~XkbLC_Default);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
XkbFile *
|
|
|
|
CreateXKBFile(int type, char *name, ParseCommon * defs, unsigned flags)
|
|
|
|
{
|
|
|
|
XkbFile *file;
|
|
|
|
static int fileID;
|
|
|
|
|
|
|
|
file = uTypedAlloc(XkbFile);
|
|
|
|
if (file)
|
|
|
|
{
|
2009-03-28 20:00:13 -06:00
|
|
|
XkbcEnsureSafeMapName(name);
|
2012-02-29 11:50:17 -07:00
|
|
|
memset(file, 0, sizeof(XkbFile));
|
2009-03-27 07:55:32 -06:00
|
|
|
file->type = type;
|
2009-04-05 21:27:35 -06:00
|
|
|
file->topName = _XkbDupString(name);
|
2009-03-27 07:55:32 -06:00
|
|
|
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;
|
|
|
|
}
|
2012-03-01 12:20:45 -07:00
|
|
|
|
|
|
|
static void
|
|
|
|
FreeStmt(ParseCommon *stmt);
|
|
|
|
|
|
|
|
static void
|
|
|
|
FreeExpr(ExprDef *expr)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!expr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (expr->op)
|
|
|
|
{
|
|
|
|
case ExprActionList:
|
|
|
|
case OpNegate:
|
|
|
|
case OpUnaryPlus:
|
|
|
|
case OpNot:
|
|
|
|
case OpInvert:
|
|
|
|
FreeStmt(&expr->value.child->common);
|
|
|
|
break;
|
|
|
|
case OpDivide:
|
|
|
|
case OpAdd:
|
|
|
|
case OpSubtract:
|
|
|
|
case OpMultiply:
|
|
|
|
case OpAssign:
|
|
|
|
FreeStmt(&expr->value.binary.left->common);
|
|
|
|
FreeStmt(&expr->value.binary.right->common);
|
|
|
|
break;
|
|
|
|
case ExprActionDecl:
|
|
|
|
FreeStmt(&expr->value.action.args->common);
|
|
|
|
break;
|
|
|
|
case ExprArrayRef:
|
|
|
|
FreeStmt(&expr->value.array.entry->common);
|
|
|
|
break;
|
|
|
|
case ExprKeysymList:
|
|
|
|
for (i = 0; i < expr->value.list.nSyms; i++)
|
|
|
|
free(expr->value.list.syms[i]);
|
|
|
|
free(expr->value.list.syms);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
FreeInclude(IncludeStmt *incl)
|
|
|
|
{
|
|
|
|
IncludeStmt *next;
|
|
|
|
|
|
|
|
while (incl)
|
|
|
|
{
|
|
|
|
next = incl->next;
|
|
|
|
|
|
|
|
free(incl->file);
|
|
|
|
free(incl->map);
|
|
|
|
free(incl->modifier);
|
|
|
|
free(incl->path);
|
|
|
|
free(incl->stmt);
|
|
|
|
|
|
|
|
free(incl);
|
|
|
|
incl = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
FreeStmt(ParseCommon *stmt)
|
|
|
|
{
|
|
|
|
ParseCommon *next;
|
|
|
|
YYSTYPE u;
|
|
|
|
|
|
|
|
while (stmt)
|
|
|
|
{
|
|
|
|
next = stmt->next;
|
|
|
|
u.any = stmt;
|
|
|
|
|
|
|
|
switch (stmt->stmtType)
|
|
|
|
{
|
|
|
|
case StmtInclude:
|
|
|
|
FreeInclude((IncludeStmt *)stmt);
|
2012-03-02 05:49:36 -07:00
|
|
|
/* stmt is already free'd here. */
|
2012-03-01 12:20:45 -07:00
|
|
|
stmt = NULL;
|
|
|
|
break;
|
|
|
|
case StmtExpr:
|
|
|
|
FreeExpr(u.expr);
|
|
|
|
break;
|
|
|
|
case StmtVarDef:
|
|
|
|
FreeStmt(&u.var->name->common);
|
|
|
|
FreeStmt(&u.var->value->common);
|
|
|
|
break;
|
|
|
|
case StmtKeyTypeDef:
|
|
|
|
FreeStmt(&u.keyType->body->common);
|
|
|
|
break;
|
|
|
|
case StmtInterpDef:
|
|
|
|
free(u.interp->sym);
|
|
|
|
FreeStmt(&u.interp->match->common);
|
|
|
|
FreeStmt(&u.interp->def->common);
|
|
|
|
break;
|
|
|
|
case StmtVModDef:
|
|
|
|
FreeStmt(&u.vmod->value->common);
|
|
|
|
break;
|
|
|
|
case StmtSymbolsDef:
|
|
|
|
FreeStmt(&u.syms->symbols->common);
|
|
|
|
break;
|
|
|
|
case StmtModMapDef:
|
|
|
|
FreeStmt(&u.modMask->keys->common);
|
|
|
|
break;
|
|
|
|
case StmtGroupCompatDef:
|
|
|
|
FreeStmt(&u.groupCompat->def->common);
|
|
|
|
break;
|
|
|
|
case StmtIndicatorMapDef:
|
|
|
|
FreeStmt(&u.ledMap->body->common);
|
|
|
|
break;
|
|
|
|
case StmtIndicatorNameDef:
|
|
|
|
FreeStmt(&u.ledName->name->common);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(stmt);
|
|
|
|
stmt = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FreeXKBFile(XkbFile *file)
|
|
|
|
{
|
|
|
|
XkbFile *next;
|
|
|
|
|
|
|
|
while (file)
|
|
|
|
{
|
|
|
|
next = (XkbFile *)file->common.next;
|
|
|
|
|
|
|
|
switch (file->type)
|
|
|
|
{
|
|
|
|
case XkmKeymapFile:
|
|
|
|
case XkmSemanticsFile:
|
|
|
|
case XkmLayoutFile:
|
|
|
|
FreeXKBFile((XkbFile *)file->defs);
|
|
|
|
break;
|
|
|
|
case XkmTypesIndex:
|
|
|
|
case XkmCompatMapIndex:
|
|
|
|
case XkmSymbolsIndex:
|
|
|
|
case XkmKeyNamesIndex:
|
|
|
|
case XkmGeometryIndex:
|
2012-03-09 09:26:34 -07:00
|
|
|
case XkmGeometryFile:
|
2012-03-01 12:20:45 -07:00
|
|
|
FreeStmt(file->defs);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(file->name);
|
2012-03-02 05:49:36 -07:00
|
|
|
free(file->topName);
|
2012-03-01 12:20:45 -07:00
|
|
|
free(file);
|
|
|
|
file = next;
|
|
|
|
}
|
|
|
|
}
|