expr: split expression types and allocate them separately
Currently, we have one ExprDef type, which contains a tagged union with the value of all expression types. Turns out, this union is quite wasteful memory-wise. Instead, create separate types for all expressions (e.g ExprBinary, ExprInteger) which embed the common fields (ExprCommon), and malloc them per their size; ExprDef then becomes a union of all these types, but is just used as a generic pointer. [Instead of making ExprDef a union, another option is to use ExprCommon as the generic pointer type and then do up-castings, like we do with ParseCommon. But this makes the code much uglier.] The diff is mostly straightforward mechanical adaptations. It could have been much smaller with the help of C11 anonymous structs (which were previously a gnu extension). This will have saved all of the 'op' -> 'expr->op', etc changes. But if we can be a bit more portable for a little effort, we should. Before (./test/rulescomp, x86 32 bit, -O2): ==12974== total heap usage: 145,217 allocs, 145,217 frees, 10,476,238 bytes allocated After: ==11145== total heap usage: 145,217 allocs, 145,217 frees, 8,270,358 bytes allocated Signed-off-by: Ran Benita <ran234@gmail.com>master
parent
068016e4dd
commit
972395b856
|
@ -56,18 +56,22 @@
|
|||
#include "expr.h"
|
||||
#include "action.h"
|
||||
|
||||
static const ExprDef constTrue = {
|
||||
.common = { .type = STMT_EXPR, .next = NULL },
|
||||
.op = EXPR_VALUE,
|
||||
.value_type = EXPR_TYPE_BOOLEAN,
|
||||
.value = { .set = true },
|
||||
static const ExprBoolean constTrue = {
|
||||
.expr = {
|
||||
.common = { .type = STMT_EXPR, .next = NULL },
|
||||
.op = EXPR_VALUE,
|
||||
.value_type = EXPR_TYPE_BOOLEAN,
|
||||
},
|
||||
.set = true,
|
||||
};
|
||||
|
||||
static const ExprDef constFalse = {
|
||||
.common = { .type = STMT_EXPR, .next = NULL },
|
||||
.op = EXPR_VALUE,
|
||||
.value_type = EXPR_TYPE_BOOLEAN,
|
||||
.value = { .set = false },
|
||||
static const ExprBoolean constFalse = {
|
||||
.expr = {
|
||||
.common = { .type = STMT_EXPR, .next = NULL },
|
||||
.op = EXPR_VALUE,
|
||||
.value_type = EXPR_TYPE_BOOLEAN,
|
||||
},
|
||||
.set = false,
|
||||
};
|
||||
|
||||
enum action_field {
|
||||
|
@ -265,9 +269,9 @@ CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action,
|
|||
const ExprDef *value, enum xkb_action_flags *flags_inout,
|
||||
xkb_mod_mask_t *mods_rtrn)
|
||||
{
|
||||
if (value->op == EXPR_IDENT) {
|
||||
if (value->expr.op == EXPR_IDENT) {
|
||||
const char *valStr;
|
||||
valStr = xkb_atom_text(keymap->ctx, value->value.ident);
|
||||
valStr = xkb_atom_text(keymap->ctx, value->ident.ident);
|
||||
if (valStr && (istreq(valStr, "usemodmapmods") ||
|
||||
istreq(valStr, "modmapmods"))) {
|
||||
|
||||
|
@ -367,9 +371,9 @@ CheckGroupField(struct xkb_keymap *keymap, unsigned action,
|
|||
{
|
||||
const ExprDef *spec;
|
||||
|
||||
if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS) {
|
||||
if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) {
|
||||
*flags_inout &= ~ACTION_ABSOLUTE_SWITCH;
|
||||
spec = value->value.child;
|
||||
spec = value->unary.child;
|
||||
}
|
||||
else {
|
||||
*flags_inout |= ACTION_ABSOLUTE_SWITCH;
|
||||
|
@ -380,9 +384,9 @@ CheckGroupField(struct xkb_keymap *keymap, unsigned action,
|
|||
return ReportMismatch(keymap, action, ACTION_FIELD_GROUP,
|
||||
"integer (range 1..8)");
|
||||
|
||||
if (value->op == EXPR_NEGATE)
|
||||
if (value->expr.op == EXPR_NEGATE)
|
||||
*grp_rtrn = -*grp_rtrn;
|
||||
else if (value->op != EXPR_UNARY_PLUS)
|
||||
else if (value->expr.op != EXPR_UNARY_PLUS)
|
||||
(*grp_rtrn)--;
|
||||
|
||||
return true;
|
||||
|
@ -472,7 +476,7 @@ HandleMovePtr(struct xkb_keymap *keymap, union xkb_action *action,
|
|||
if (field == ACTION_FIELD_X || field == ACTION_FIELD_Y) {
|
||||
int val;
|
||||
|
||||
if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS)
|
||||
if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS)
|
||||
absolute = false;
|
||||
else
|
||||
absolute = true;
|
||||
|
@ -613,9 +617,10 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
|
|||
if (array_ndx)
|
||||
return ReportActionNotArray(keymap, action->type, field);
|
||||
|
||||
if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS) {
|
||||
if (value->expr.op == EXPR_NEGATE ||
|
||||
value->expr.op == EXPR_UNARY_PLUS) {
|
||||
act->flags &= ~ACTION_ABSOLUTE_SWITCH;
|
||||
button = value->value.child;
|
||||
button = value->unary.child;
|
||||
}
|
||||
else {
|
||||
act->flags |= ACTION_ABSOLUTE_SWITCH;
|
||||
|
@ -639,7 +644,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
|
|||
return false;
|
||||
}
|
||||
|
||||
act->value = (value->op == EXPR_NEGATE ? -btn: btn);
|
||||
act->value = (value->expr.op == EXPR_NEGATE ? -btn: btn);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -660,9 +665,10 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
|
|||
if (array_ndx)
|
||||
return ReportActionNotArray(keymap, action->type, field);
|
||||
|
||||
if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS) {
|
||||
if (value->expr.op == EXPR_NEGATE ||
|
||||
value->expr.op == EXPR_UNARY_PLUS) {
|
||||
act->flags &= ~ACTION_ABSOLUTE_SWITCH;
|
||||
scrn = value->value.child;
|
||||
scrn = value->unary.child;
|
||||
}
|
||||
else {
|
||||
act->flags |= ACTION_ABSOLUTE_SWITCH;
|
||||
|
@ -680,7 +686,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
|
|||
return false;
|
||||
}
|
||||
|
||||
act->screen = (value->op == EXPR_NEGATE ? -val : val);
|
||||
act->screen = (value->expr.op == EXPR_NEGATE ? -val : val);
|
||||
return true;
|
||||
}
|
||||
else if (field == ACTION_FIELD_SAME) {
|
||||
|
@ -861,13 +867,13 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
|
|||
const char *str;
|
||||
unsigned handler_type;
|
||||
|
||||
if (def->op != EXPR_ACTION_DECL) {
|
||||
if (def->expr.op != EXPR_ACTION_DECL) {
|
||||
log_err(keymap->ctx, "Expected an action definition, found %s\n",
|
||||
expr_op_type_to_string(def->op));
|
||||
expr_op_type_to_string(def->expr.op));
|
||||
return false;
|
||||
}
|
||||
|
||||
str = xkb_atom_text(keymap->ctx, def->value.action.name);
|
||||
str = xkb_atom_text(keymap->ctx, def->action.name);
|
||||
if (!stringToAction(str, &handler_type)) {
|
||||
log_err(keymap->ctx, "Unknown action %s\n", str);
|
||||
return false;
|
||||
|
@ -885,24 +891,24 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
|
|||
* particular instance, e.g. "modifiers" and "clearLocks" in:
|
||||
* SetMods(modifiers=Alt,clearLocks);
|
||||
*/
|
||||
for (arg = def->value.action.args; arg != NULL;
|
||||
for (arg = def->action.args; arg != NULL;
|
||||
arg = (ExprDef *) arg->common.next) {
|
||||
const ExprDef *value;
|
||||
ExprDef *field, *arrayRtrn;
|
||||
const char *elemRtrn, *fieldRtrn;
|
||||
enum action_field fieldNdx;
|
||||
|
||||
if (arg->op == EXPR_ASSIGN) {
|
||||
field = arg->value.binary.left;
|
||||
value = arg->value.binary.right;
|
||||
if (arg->expr.op == EXPR_ASSIGN) {
|
||||
field = arg->binary.left;
|
||||
value = arg->binary.right;
|
||||
}
|
||||
else if (arg->op == EXPR_NOT || arg->op == EXPR_INVERT) {
|
||||
field = arg->value.child;
|
||||
value = &constFalse;
|
||||
else if (arg->expr.op == EXPR_NOT || arg->expr.op == EXPR_INVERT) {
|
||||
field = arg->unary.child;
|
||||
value = (const ExprDef *) &constFalse;
|
||||
}
|
||||
else {
|
||||
field = arg;
|
||||
value = &constTrue;
|
||||
value = (const ExprDef *) &constTrue;
|
||||
}
|
||||
|
||||
if (!ExprResolveLhs(keymap->ctx, field, &elemRtrn, &fieldRtrn,
|
||||
|
|
|
@ -71,16 +71,16 @@ AppendStmt(ParseCommon *to, ParseCommon *append)
|
|||
}
|
||||
|
||||
static ExprDef *
|
||||
ExprCreate(enum expr_op_type op, enum expr_value_type type)
|
||||
ExprCreate(enum expr_op_type op, enum expr_value_type type, size_t size)
|
||||
{
|
||||
ExprDef *expr = malloc(sizeof(*expr));
|
||||
ExprDef *expr = malloc(size);
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
expr->common.type = STMT_EXPR;
|
||||
expr->common.next = NULL;
|
||||
expr->op = op;
|
||||
expr->value_type = type;
|
||||
expr->expr.op = op;
|
||||
expr->expr.value_type = type;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -88,11 +88,12 @@ ExprCreate(enum expr_op_type op, enum expr_value_type type)
|
|||
ExprDef *
|
||||
ExprCreateString(xkb_atom_t str)
|
||||
{
|
||||
ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING);
|
||||
ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING,
|
||||
sizeof(ExprString));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
expr->value.str = str;
|
||||
expr->string.str = str;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -100,11 +101,12 @@ ExprCreateString(xkb_atom_t str)
|
|||
ExprDef *
|
||||
ExprCreateInteger(int ival)
|
||||
{
|
||||
ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT);
|
||||
ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT,
|
||||
sizeof(ExprInteger));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
expr->value.ival = ival;
|
||||
expr->integer.ival = ival;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -112,11 +114,12 @@ ExprCreateInteger(int ival)
|
|||
ExprDef *
|
||||
ExprCreateBoolean(bool set)
|
||||
{
|
||||
ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN);
|
||||
ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN,
|
||||
sizeof(ExprBoolean));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
expr->value.set = set;
|
||||
expr->boolean.set = set;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -124,11 +127,12 @@ ExprCreateBoolean(bool set)
|
|||
ExprDef *
|
||||
ExprCreateKeyName(xkb_atom_t key_name)
|
||||
{
|
||||
ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME);
|
||||
ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME,
|
||||
sizeof(ExprKeyName));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
expr->value.keyName = key_name;
|
||||
expr->key_name.key_name = key_name;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -136,11 +140,12 @@ ExprCreateKeyName(xkb_atom_t key_name)
|
|||
ExprDef *
|
||||
ExprCreateIdent(xkb_atom_t ident)
|
||||
{
|
||||
ExprDef *expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
|
||||
ExprDef *expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN,
|
||||
sizeof(ExprIdent));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
expr->value.ident = ident;
|
||||
expr->ident.ident = ident;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -149,11 +154,12 @@ ExprDef *
|
|||
ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
|
||||
ExprDef *child)
|
||||
{
|
||||
ExprDef *expr = ExprCreate(op, type);
|
||||
ExprDef *expr = ExprCreate(op, type,
|
||||
sizeof(ExprUnary));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
expr->value.child = child;
|
||||
expr->unary.child = child;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -161,17 +167,18 @@ ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
|
|||
ExprDef *
|
||||
ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
|
||||
{
|
||||
ExprDef *expr = ExprCreate(op, EXPR_TYPE_UNKNOWN);
|
||||
ExprDef *expr = ExprCreate(op, EXPR_TYPE_UNKNOWN,
|
||||
sizeof(ExprBinary));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
if (op == EXPR_ASSIGN || left->value_type == EXPR_TYPE_UNKNOWN)
|
||||
expr->value_type = right->value_type;
|
||||
else if (left->value_type == right->value_type ||
|
||||
right->value_type == EXPR_TYPE_UNKNOWN)
|
||||
expr->value_type = left->value_type;
|
||||
expr->value.binary.left = left;
|
||||
expr->value.binary.right = right;
|
||||
if (op == EXPR_ASSIGN || left->expr.value_type == EXPR_TYPE_UNKNOWN)
|
||||
expr->expr.value_type = right->expr.value_type;
|
||||
else if (left->expr.value_type == right->expr.value_type ||
|
||||
right->expr.value_type == EXPR_TYPE_UNKNOWN)
|
||||
expr->expr.value_type = left->expr.value_type;
|
||||
expr->binary.left = left;
|
||||
expr->binary.right = right;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -179,12 +186,13 @@ ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
|
|||
ExprDef *
|
||||
ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field)
|
||||
{
|
||||
ExprDef *expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN);
|
||||
ExprDef *expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN,
|
||||
sizeof(ExprFieldRef));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
expr->value.field.element = element;
|
||||
expr->value.field.field = field;
|
||||
expr->field_ref.element = element;
|
||||
expr->field_ref.field = field;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -192,13 +200,14 @@ ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field)
|
|||
ExprDef *
|
||||
ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry)
|
||||
{
|
||||
ExprDef *expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
|
||||
ExprDef *expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN,
|
||||
sizeof(ExprArrayRef));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
expr->value.array.element = element;
|
||||
expr->value.array.field = field;
|
||||
expr->value.array.entry = entry;
|
||||
expr->array_ref.element = element;
|
||||
expr->array_ref.field = field;
|
||||
expr->array_ref.entry = entry;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -266,8 +275,8 @@ VarCreate(ExprDef *name, ExprDef *value)
|
|||
VarDef *
|
||||
BoolVarCreate(xkb_atom_t ident, bool set)
|
||||
{
|
||||
return VarCreate(ExprCreateIdent(ident),
|
||||
ExprCreateBoolean(set));
|
||||
return VarCreate((ExprDef *) ExprCreateIdent(ident),
|
||||
(ExprDef *) ExprCreateBoolean(set));
|
||||
}
|
||||
|
||||
InterpDef *
|
||||
|
@ -385,75 +394,76 @@ LedNameCreate(int ndx, ExprDef *name, bool virtual)
|
|||
ExprDef *
|
||||
ActionCreate(xkb_atom_t name, ExprDef *args)
|
||||
{
|
||||
ExprDef *act = ExprCreate(EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN);
|
||||
if (!act)
|
||||
ExprDef *expr = ExprCreate(EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN,
|
||||
sizeof(ExprAction));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
act->value.action.name = name;
|
||||
act->value.action.args = args;
|
||||
expr->action.name = name;
|
||||
expr->action.args = args;
|
||||
|
||||
return act;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
CreateKeysymList(xkb_keysym_t sym)
|
||||
{
|
||||
ExprDef *def = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
|
||||
if (!def)
|
||||
ExprDef *expr = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS,
|
||||
sizeof(ExprKeysymList));
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
darray_init(def->value.list.syms);
|
||||
darray_init(def->value.list.symsMapIndex);
|
||||
darray_init(def->value.list.symsNumEntries);
|
||||
darray_init(expr->keysym_list.syms);
|
||||
darray_init(expr->keysym_list.symsMapIndex);
|
||||
darray_init(expr->keysym_list.symsNumEntries);
|
||||
|
||||
darray_append(def->value.list.syms, sym);
|
||||
darray_append(def->value.list.symsMapIndex, 0);
|
||||
darray_append(def->value.list.symsNumEntries, 1);
|
||||
darray_append(expr->keysym_list.syms, sym);
|
||||
darray_append(expr->keysym_list.symsMapIndex, 0);
|
||||
darray_append(expr->keysym_list.symsNumEntries, 1);
|
||||
|
||||
return def;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
CreateMultiKeysymList(ExprDef *list)
|
||||
CreateMultiKeysymList(ExprDef *expr)
|
||||
{
|
||||
size_t nLevels = darray_size(list->value.list.symsMapIndex);
|
||||
size_t nLevels = darray_size(expr->keysym_list.symsMapIndex);
|
||||
|
||||
darray_resize(list->value.list.symsMapIndex, 1);
|
||||
darray_resize(list->value.list.symsNumEntries, 1);
|
||||
darray_item(list->value.list.symsMapIndex, 0) = 0;
|
||||
darray_item(list->value.list.symsNumEntries, 0) = nLevels;
|
||||
darray_resize(expr->keysym_list.symsMapIndex, 1);
|
||||
darray_resize(expr->keysym_list.symsNumEntries, 1);
|
||||
darray_item(expr->keysym_list.symsMapIndex, 0) = 0;
|
||||
darray_item(expr->keysym_list.symsNumEntries, 0) = nLevels;
|
||||
|
||||
return list;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
AppendKeysymList(ExprDef *list, xkb_keysym_t sym)
|
||||
AppendKeysymList(ExprDef *expr, xkb_keysym_t sym)
|
||||
{
|
||||
size_t nSyms = darray_size(list->value.list.syms);
|
||||
size_t nSyms = darray_size(expr->keysym_list.syms);
|
||||
|
||||
darray_append(list->value.list.symsMapIndex, nSyms);
|
||||
darray_append(list->value.list.symsNumEntries, 1);
|
||||
darray_append(list->value.list.syms, sym);
|
||||
darray_append(expr->keysym_list.symsMapIndex, nSyms);
|
||||
darray_append(expr->keysym_list.symsNumEntries, 1);
|
||||
darray_append(expr->keysym_list.syms, sym);
|
||||
|
||||
return list;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
AppendMultiKeysymList(ExprDef *list, ExprDef *append)
|
||||
AppendMultiKeysymList(ExprDef *expr, ExprDef *append)
|
||||
{
|
||||
size_t nSyms = darray_size(list->value.list.syms);
|
||||
size_t numEntries = darray_size(append->value.list.syms);
|
||||
size_t nSyms = darray_size(expr->keysym_list.syms);
|
||||
size_t numEntries = darray_size(append->keysym_list.syms);
|
||||
|
||||
darray_append(list->value.list.symsMapIndex, nSyms);
|
||||
darray_append(list->value.list.symsNumEntries, numEntries);
|
||||
darray_append_items(list->value.list.syms,
|
||||
darray_mem(append->value.list.syms, 0),
|
||||
numEntries);
|
||||
darray_append(expr->keysym_list.symsMapIndex, nSyms);
|
||||
darray_append(expr->keysym_list.symsNumEntries, numEntries);
|
||||
darray_append_items(expr->keysym_list.syms,
|
||||
darray_mem(append->keysym_list.syms, 0), numEntries);
|
||||
|
||||
darray_resize(append->value.list.syms, 0);
|
||||
darray_resize(append->keysym_list.syms, 0);
|
||||
FreeStmt(&append->common);
|
||||
|
||||
return list;
|
||||
return expr;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -619,13 +629,13 @@ FreeExpr(ExprDef *expr)
|
|||
if (!expr)
|
||||
return;
|
||||
|
||||
switch (expr->op) {
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_ACTION_LIST:
|
||||
case EXPR_NEGATE:
|
||||
case EXPR_UNARY_PLUS:
|
||||
case EXPR_NOT:
|
||||
case EXPR_INVERT:
|
||||
FreeStmt(&expr->value.child->common);
|
||||
FreeStmt(&expr->unary.child->common);
|
||||
break;
|
||||
|
||||
case EXPR_DIVIDE:
|
||||
|
@ -633,22 +643,22 @@ FreeExpr(ExprDef *expr)
|
|||
case EXPR_SUBTRACT:
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_ASSIGN:
|
||||
FreeStmt(&expr->value.binary.left->common);
|
||||
FreeStmt(&expr->value.binary.right->common);
|
||||
FreeStmt(&expr->binary.left->common);
|
||||
FreeStmt(&expr->binary.right->common);
|
||||
break;
|
||||
|
||||
case EXPR_ACTION_DECL:
|
||||
FreeStmt(&expr->value.action.args->common);
|
||||
FreeStmt(&expr->action.args->common);
|
||||
break;
|
||||
|
||||
case EXPR_ARRAY_REF:
|
||||
FreeStmt(&expr->value.array.entry->common);
|
||||
FreeStmt(&expr->array_ref.entry->common);
|
||||
break;
|
||||
|
||||
case EXPR_KEYSYM_LIST:
|
||||
darray_free(expr->value.list.syms);
|
||||
darray_free(expr->value.list.symsMapIndex);
|
||||
darray_free(expr->value.list.symsNumEntries);
|
||||
darray_free(expr->keysym_list.syms);
|
||||
darray_free(expr->keysym_list.symsMapIndex);
|
||||
darray_free(expr->keysym_list.symsNumEntries);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -158,41 +158,92 @@ typedef struct _IncludeStmt {
|
|||
struct _IncludeStmt *next_incl;
|
||||
} IncludeStmt;
|
||||
|
||||
typedef struct _Expr {
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum expr_op_type op;
|
||||
enum expr_value_type value_type;
|
||||
union {
|
||||
struct {
|
||||
struct _Expr *left;
|
||||
struct _Expr *right;
|
||||
} binary;
|
||||
struct {
|
||||
xkb_atom_t element;
|
||||
xkb_atom_t field;
|
||||
} field;
|
||||
struct {
|
||||
xkb_atom_t element;
|
||||
xkb_atom_t field;
|
||||
struct _Expr *entry;
|
||||
} array;
|
||||
struct {
|
||||
xkb_atom_t name;
|
||||
struct _Expr *args;
|
||||
} action;
|
||||
struct {
|
||||
darray(xkb_keysym_t) syms;
|
||||
darray(int) symsMapIndex;
|
||||
darray(unsigned int) symsNumEntries;
|
||||
} list;
|
||||
struct _Expr *child;
|
||||
xkb_atom_t ident;
|
||||
xkb_atom_t str;
|
||||
bool set;
|
||||
int ival;
|
||||
xkb_atom_t keyName;
|
||||
} value;
|
||||
} ExprDef;
|
||||
} ExprCommon;
|
||||
|
||||
typedef union ExprDef ExprDef;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t ident;
|
||||
} ExprIdent;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t str;
|
||||
} ExprString;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
bool set;
|
||||
} ExprBoolean;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
int ival;
|
||||
} ExprInteger;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t key_name;
|
||||
} ExprKeyName;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
ExprDef *left;
|
||||
ExprDef *right;
|
||||
} ExprBinary;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
ExprDef *child;
|
||||
} ExprUnary;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t element;
|
||||
xkb_atom_t field;
|
||||
} ExprFieldRef;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t element;
|
||||
xkb_atom_t field;
|
||||
ExprDef *entry;
|
||||
} ExprArrayRef;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t name;
|
||||
ExprDef *args;
|
||||
} ExprAction;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
darray(xkb_keysym_t) syms;
|
||||
darray(int) symsMapIndex;
|
||||
darray(unsigned int) symsNumEntries;
|
||||
} ExprKeysymList;
|
||||
|
||||
union ExprDef {
|
||||
ParseCommon common;
|
||||
/* Maybe someday we can use C11 anonymous struct for ExprCommon here. */
|
||||
ExprCommon expr;
|
||||
ExprIdent ident;
|
||||
ExprString string;
|
||||
ExprBoolean boolean;
|
||||
ExprInteger integer;
|
||||
ExprKeyName key_name;
|
||||
ExprBinary binary;
|
||||
ExprUnary unary;
|
||||
ExprFieldRef field_ref;
|
||||
ExprArrayRef array_ref;
|
||||
ExprAction action;
|
||||
ExprKeysymList keysym_list;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
|
|
|
@ -432,19 +432,19 @@ ResolveStateAndPredicate(ExprDef *expr, enum xkb_match_operation *pred_rtrn,
|
|||
}
|
||||
|
||||
*pred_rtrn = MATCH_EXACTLY;
|
||||
if (expr->op == EXPR_ACTION_DECL) {
|
||||
if (expr->expr.op == EXPR_ACTION_DECL) {
|
||||
const char *pred_txt = xkb_atom_text(info->keymap->ctx,
|
||||
expr->value.action.name);
|
||||
expr->action.name);
|
||||
if (!LookupString(symInterpretMatchMaskNames, pred_txt, pred_rtrn)) {
|
||||
log_err(info->keymap->ctx,
|
||||
"Illegal modifier predicate \"%s\"; Ignored\n", pred_txt);
|
||||
return false;
|
||||
}
|
||||
expr = expr->value.action.args;
|
||||
expr = expr->action.args;
|
||||
}
|
||||
else if (expr->op == EXPR_IDENT) {
|
||||
else if (expr->expr.op == EXPR_IDENT) {
|
||||
const char *pred_txt = xkb_atom_text(info->keymap->ctx,
|
||||
expr->value.ident);
|
||||
expr->ident.ident);
|
||||
if (pred_txt && istreq(pred_txt, "any")) {
|
||||
*pred_rtrn = MATCH_ANY;
|
||||
*mods_rtrn = MOD_REAL_MASK_ALL;
|
||||
|
@ -805,7 +805,7 @@ HandleInterpBody(CompatInfo *info, VarDef *def, SymInterpInfo *si)
|
|||
ExprDef *arrayNdx;
|
||||
|
||||
for (; def; def = (VarDef *) def->common.next) {
|
||||
if (def->name && def->name->op == EXPR_FIELD_REF) {
|
||||
if (def->name && def->name->expr.op == EXPR_FIELD_REF) {
|
||||
log_err(info->keymap->ctx,
|
||||
"Cannot set a global default value from within an interpret statement; "
|
||||
"Move statements to the global file scope\n");
|
||||
|
|
|
@ -37,26 +37,26 @@ ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr,
|
|||
const char **elem_rtrn, const char **field_rtrn,
|
||||
ExprDef **index_rtrn)
|
||||
{
|
||||
switch (expr->op) {
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_IDENT:
|
||||
*elem_rtrn = NULL;
|
||||
*field_rtrn = xkb_atom_text(ctx, expr->value.ident);
|
||||
*field_rtrn = xkb_atom_text(ctx, expr->ident.ident);
|
||||
*index_rtrn = NULL;
|
||||
return true;
|
||||
case EXPR_FIELD_REF:
|
||||
*elem_rtrn = xkb_atom_text(ctx, expr->value.field.element);
|
||||
*field_rtrn = xkb_atom_text(ctx, expr->value.field.field);
|
||||
*elem_rtrn = xkb_atom_text(ctx, expr->field_ref.element);
|
||||
*field_rtrn = xkb_atom_text(ctx, expr->field_ref.field);
|
||||
*index_rtrn = NULL;
|
||||
return true;
|
||||
case EXPR_ARRAY_REF:
|
||||
*elem_rtrn = xkb_atom_text(ctx, expr->value.array.element);
|
||||
*field_rtrn = xkb_atom_text(ctx, expr->value.array.field);
|
||||
*index_rtrn = expr->value.array.entry;
|
||||
*elem_rtrn = xkb_atom_text(ctx, expr->array_ref.element);
|
||||
*field_rtrn = xkb_atom_text(ctx, expr->array_ref.field);
|
||||
*index_rtrn = expr->array_ref.entry;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
log_wsgo(ctx, "Unexpected operator %d in ResolveLhs\n", expr->op);
|
||||
log_wsgo(ctx, "Unexpected operator %d in ResolveLhs\n", expr->expr.op);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -127,19 +127,19 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
|
|||
bool ok = false;
|
||||
const char *ident;
|
||||
|
||||
switch (expr->op) {
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_VALUE:
|
||||
if (expr->value_type != EXPR_TYPE_BOOLEAN) {
|
||||
if (expr->expr.value_type != EXPR_TYPE_BOOLEAN) {
|
||||
log_err(ctx,
|
||||
"Found constant of type %s where boolean was expected\n",
|
||||
expr_value_type_to_string(expr->value_type));
|
||||
expr_value_type_to_string(expr->expr.value_type));
|
||||
return false;
|
||||
}
|
||||
*set_rtrn = expr->value.set;
|
||||
*set_rtrn = expr->boolean.set;
|
||||
return true;
|
||||
|
||||
case EXPR_IDENT:
|
||||
ident = xkb_atom_text(ctx, expr->value.ident);
|
||||
ident = xkb_atom_text(ctx, expr->ident.ident);
|
||||
if (ident) {
|
||||
if (istreq(ident, "true") ||
|
||||
istreq(ident, "yes") ||
|
||||
|
@ -154,14 +154,13 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
|
|||
return true;
|
||||
}
|
||||
}
|
||||
log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n",
|
||||
xkb_atom_text(ctx, expr->value.ident));
|
||||
log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n", ident);
|
||||
return false;
|
||||
|
||||
case EXPR_FIELD_REF:
|
||||
log_err(ctx, "Default \"%s.%s\" of type boolean is unknown\n",
|
||||
xkb_atom_text(ctx, expr->value.field.element),
|
||||
xkb_atom_text(ctx, expr->value.field.field));
|
||||
xkb_atom_text(ctx, expr->field_ref.element),
|
||||
xkb_atom_text(ctx, expr->field_ref.field));
|
||||
return false;
|
||||
|
||||
case EXPR_INVERT:
|
||||
|
@ -178,11 +177,12 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
|
|||
case EXPR_NEGATE:
|
||||
case EXPR_UNARY_PLUS:
|
||||
log_err(ctx, "%s of boolean values not permitted\n",
|
||||
expr_op_type_to_string(expr->op));
|
||||
expr_op_type_to_string(expr->expr.op));
|
||||
break;
|
||||
|
||||
default:
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveBoolean\n", expr->op);
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveBoolean\n",
|
||||
expr->expr.op);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -194,32 +194,28 @@ ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
|
|||
xkb_keycode_t *kc)
|
||||
{
|
||||
xkb_keycode_t leftRtrn, rightRtrn;
|
||||
ExprDef *left, *right;
|
||||
|
||||
switch (expr->op) {
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_VALUE:
|
||||
if (expr->value_type != EXPR_TYPE_INT) {
|
||||
if (expr->expr.value_type != EXPR_TYPE_INT) {
|
||||
log_err(ctx,
|
||||
"Found constant of type %s where an int was expected\n",
|
||||
expr_value_type_to_string(expr->value_type));
|
||||
expr_value_type_to_string(expr->expr.value_type));
|
||||
return false;
|
||||
}
|
||||
|
||||
*kc = (xkb_keycode_t) expr->value.ival;
|
||||
*kc = (xkb_keycode_t) expr->integer.ival;
|
||||
return true;
|
||||
|
||||
case EXPR_ADD:
|
||||
case EXPR_SUBTRACT:
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_DIVIDE:
|
||||
left = expr->value.binary.left;
|
||||
right = expr->value.binary.right;
|
||||
|
||||
if (!ExprResolveKeyCode(ctx, left, &leftRtrn) ||
|
||||
!ExprResolveKeyCode(ctx, right, &rightRtrn))
|
||||
if (!ExprResolveKeyCode(ctx, expr->binary.left, &leftRtrn) ||
|
||||
!ExprResolveKeyCode(ctx, expr->binary.right, &rightRtrn))
|
||||
return false;
|
||||
|
||||
switch (expr->op) {
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_ADD:
|
||||
*kc = leftRtrn + rightRtrn;
|
||||
break;
|
||||
|
@ -245,19 +241,18 @@ ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
|
|||
return true;
|
||||
|
||||
case EXPR_NEGATE:
|
||||
left = expr->value.child;
|
||||
if (!ExprResolveKeyCode(ctx, left, &leftRtrn))
|
||||
if (!ExprResolveKeyCode(ctx, expr->unary.child, &leftRtrn))
|
||||
return false;
|
||||
|
||||
*kc = ~leftRtrn;
|
||||
return true;
|
||||
|
||||
case EXPR_UNARY_PLUS:
|
||||
left = expr->value.child;
|
||||
return ExprResolveKeyCode(ctx, left, kc);
|
||||
return ExprResolveKeyCode(ctx, expr->unary.child, kc);
|
||||
|
||||
default:
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveKeyCode\n", expr->op);
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveKeyCode\n",
|
||||
expr->expr.op);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -284,25 +279,25 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
|
|||
unsigned u;
|
||||
ExprDef *left, *right;
|
||||
|
||||
switch (expr->op) {
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_VALUE:
|
||||
if (expr->value_type != EXPR_TYPE_INT) {
|
||||
if (expr->expr.value_type != EXPR_TYPE_INT) {
|
||||
log_err(ctx,
|
||||
"Found constant of type %s where an int was expected\n",
|
||||
expr_value_type_to_string(expr->value_type));
|
||||
expr_value_type_to_string(expr->expr.value_type));
|
||||
return false;
|
||||
}
|
||||
|
||||
*val_rtrn = expr->value.ival;
|
||||
*val_rtrn = expr->integer.ival;
|
||||
return true;
|
||||
|
||||
case EXPR_IDENT:
|
||||
if (lookup)
|
||||
ok = lookup(ctx, lookupPriv, expr->value.ident, EXPR_TYPE_INT, &u);
|
||||
ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT, &u);
|
||||
|
||||
if (!ok)
|
||||
log_err(ctx, "Identifier \"%s\" of type int is unknown\n",
|
||||
xkb_atom_text(ctx, expr->value.ident));
|
||||
xkb_atom_text(ctx, expr->ident.ident));
|
||||
else
|
||||
*val_rtrn = (int) u;
|
||||
|
||||
|
@ -310,21 +305,21 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
|
|||
|
||||
case EXPR_FIELD_REF:
|
||||
log_err(ctx, "Default \"%s.%s\" of type int is unknown\n",
|
||||
xkb_atom_text(ctx, expr->value.field.element),
|
||||
xkb_atom_text(ctx, expr->value.field.field));
|
||||
xkb_atom_text(ctx, expr->field_ref.element),
|
||||
xkb_atom_text(ctx, expr->field_ref.field));
|
||||
return false;
|
||||
|
||||
case EXPR_ADD:
|
||||
case EXPR_SUBTRACT:
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_DIVIDE:
|
||||
left = expr->value.binary.left;
|
||||
right = expr->value.binary.right;
|
||||
left = expr->binary.left;
|
||||
right = expr->binary.right;
|
||||
if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv) ||
|
||||
!ExprResolveIntegerLookup(ctx, right, &r, lookup, lookupPriv))
|
||||
return false;
|
||||
|
||||
switch (expr->op) {
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_ADD:
|
||||
*val_rtrn = l + r;
|
||||
break;
|
||||
|
@ -357,20 +352,21 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
|
|||
|
||||
case EXPR_INVERT:
|
||||
case EXPR_NEGATE:
|
||||
left = expr->value.child;
|
||||
left = expr->unary.child;
|
||||
if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv))
|
||||
return false;
|
||||
|
||||
*val_rtrn = (expr->op == EXPR_NEGATE ? -l : ~l);
|
||||
*val_rtrn = (expr->expr.op == EXPR_NEGATE ? -l : ~l);
|
||||
return true;
|
||||
|
||||
case EXPR_UNARY_PLUS:
|
||||
left = expr->value.child;
|
||||
left = expr->unary.child;
|
||||
return ExprResolveIntegerLookup(ctx, left, val_rtrn, lookup,
|
||||
lookupPriv);
|
||||
|
||||
default:
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveInteger\n", expr->op);
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveInteger\n",
|
||||
expr->expr.op);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -445,26 +441,26 @@ bool
|
|||
ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_atom_t *val_rtrn)
|
||||
{
|
||||
switch (expr->op) {
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_VALUE:
|
||||
if (expr->value_type != EXPR_TYPE_STRING) {
|
||||
if (expr->expr.value_type != EXPR_TYPE_STRING) {
|
||||
log_err(ctx, "Found constant of type %s, expected a string\n",
|
||||
expr_value_type_to_string(expr->value_type));
|
||||
expr_value_type_to_string(expr->expr.value_type));
|
||||
return false;
|
||||
}
|
||||
|
||||
*val_rtrn = expr->value.str;
|
||||
*val_rtrn = expr->string.str;
|
||||
return true;
|
||||
|
||||
case EXPR_IDENT:
|
||||
log_err(ctx, "Identifier \"%s\" of type string not found\n",
|
||||
xkb_atom_text(ctx, expr->value.ident));
|
||||
xkb_atom_text(ctx, expr->ident.ident));
|
||||
return false;
|
||||
|
||||
case EXPR_FIELD_REF:
|
||||
log_err(ctx, "Default \"%s.%s\" of type string not found\n",
|
||||
xkb_atom_text(ctx, expr->value.field.element),
|
||||
xkb_atom_text(ctx, expr->value.field.field));
|
||||
xkb_atom_text(ctx, expr->field_ref.element),
|
||||
xkb_atom_text(ctx, expr->field_ref.field));
|
||||
return false;
|
||||
|
||||
case EXPR_ADD:
|
||||
|
@ -477,11 +473,12 @@ ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
|
|||
case EXPR_NOT:
|
||||
case EXPR_UNARY_PLUS:
|
||||
log_err(ctx, "%s of strings not permitted\n",
|
||||
expr_op_type_to_string(expr->op));
|
||||
expr_op_type_to_string(expr->expr.op));
|
||||
return false;
|
||||
|
||||
default:
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveString\n", expr->op);
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveString\n",
|
||||
expr->expr.op);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
@ -491,16 +488,16 @@ bool
|
|||
ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr,
|
||||
unsigned int *val_rtrn, const LookupEntry *values)
|
||||
{
|
||||
if (expr->op != EXPR_IDENT) {
|
||||
if (expr->expr.op != EXPR_IDENT) {
|
||||
log_err(ctx, "Found a %s where an enumerated value was expected\n",
|
||||
expr_op_type_to_string(expr->op));
|
||||
expr_op_type_to_string(expr->expr.op));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SimpleLookup(ctx, values, expr->value.ident, EXPR_TYPE_INT,
|
||||
if (!SimpleLookup(ctx, values, expr->ident.ident, EXPR_TYPE_INT,
|
||||
val_rtrn)) {
|
||||
log_err(ctx, "Illegal identifier %s; expected one of:\n",
|
||||
xkb_atom_text(ctx, expr->value.ident));
|
||||
xkb_atom_text(ctx, expr->ident.ident));
|
||||
while (values && values->name)
|
||||
{
|
||||
log_err(ctx, "\t%s\n", values->name);
|
||||
|
@ -523,29 +520,29 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
|
|||
ExprDef *left, *right;
|
||||
const char *bogus = NULL;
|
||||
|
||||
switch (expr->op) {
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_VALUE:
|
||||
if (expr->value_type != EXPR_TYPE_INT) {
|
||||
if (expr->expr.value_type != EXPR_TYPE_INT) {
|
||||
log_err(ctx,
|
||||
"Found constant of type %s where a mask was expected\n",
|
||||
expr_value_type_to_string(expr->value_type));
|
||||
expr_value_type_to_string(expr->expr.value_type));
|
||||
return false;
|
||||
}
|
||||
*val_rtrn = (unsigned int) expr->value.ival;
|
||||
*val_rtrn = (unsigned int) expr->integer.ival;
|
||||
return true;
|
||||
|
||||
case EXPR_IDENT:
|
||||
ok = lookup(ctx, lookupPriv, expr->value.ident, EXPR_TYPE_INT,
|
||||
ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT,
|
||||
val_rtrn);
|
||||
if (!ok)
|
||||
log_err(ctx, "Identifier \"%s\" of type int is unknown\n",
|
||||
xkb_atom_text(ctx, expr->value.ident));
|
||||
xkb_atom_text(ctx, expr->ident.ident));
|
||||
return ok;
|
||||
|
||||
case EXPR_FIELD_REF:
|
||||
log_err(ctx, "Default \"%s.%s\" of type int is unknown\n",
|
||||
xkb_atom_text(ctx, expr->value.field.element),
|
||||
xkb_atom_text(ctx, expr->value.field.field));
|
||||
xkb_atom_text(ctx, expr->field_ref.element),
|
||||
xkb_atom_text(ctx, expr->field_ref.field));
|
||||
return false;
|
||||
|
||||
case EXPR_ARRAY_REF:
|
||||
|
@ -563,13 +560,13 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
|
|||
case EXPR_SUBTRACT:
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_DIVIDE:
|
||||
left = expr->value.binary.left;
|
||||
right = expr->value.binary.right;
|
||||
left = expr->binary.left;
|
||||
right = expr->binary.right;
|
||||
if (!ExprResolveMaskLookup(ctx, left, &l, lookup, lookupPriv) ||
|
||||
!ExprResolveMaskLookup(ctx, right, &r, lookup, lookupPriv))
|
||||
return false;
|
||||
|
||||
switch (expr->op) {
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_ADD:
|
||||
*val_rtrn = l | r;
|
||||
break;
|
||||
|
@ -579,7 +576,7 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
|
|||
case EXPR_MULTIPLY:
|
||||
case EXPR_DIVIDE:
|
||||
log_err(ctx, "Cannot %s masks; Illegal operation ignored\n",
|
||||
(expr->op == EXPR_DIVIDE ? "divide" : "multiply"));
|
||||
(expr->expr.op == EXPR_DIVIDE ? "divide" : "multiply"));
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
|
@ -592,7 +589,7 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
|
|||
break;
|
||||
|
||||
case EXPR_INVERT:
|
||||
left = expr->value.child;
|
||||
left = expr->unary.child;
|
||||
if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
|
||||
return false;
|
||||
|
||||
|
@ -602,14 +599,15 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
|
|||
case EXPR_UNARY_PLUS:
|
||||
case EXPR_NEGATE:
|
||||
case EXPR_NOT:
|
||||
left = expr->value.child;
|
||||
left = expr->unary.child;
|
||||
if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
|
||||
log_err(ctx, "The %s operator cannot be used with a mask\n",
|
||||
(expr->op == EXPR_NEGATE ? "-" : "!"));
|
||||
(expr->expr.op == EXPR_NEGATE ? "-" : "!"));
|
||||
return false;
|
||||
|
||||
default:
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveMask\n", expr->op);
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveMask\n",
|
||||
expr->expr.op);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -638,9 +636,8 @@ ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
|
|||
{
|
||||
int val;
|
||||
|
||||
if (expr->op == EXPR_IDENT) {
|
||||
const char *str;
|
||||
str = xkb_atom_text(ctx, expr->value.ident);
|
||||
if (expr->expr.op == EXPR_IDENT) {
|
||||
const char *str = xkb_atom_text(ctx, expr->ident.ident);
|
||||
*sym_rtrn = xkb_keysym_from_name(str, 0);
|
||||
if (*sym_rtrn != XKB_KEY_NoSymbol)
|
||||
return true;
|
||||
|
@ -652,7 +649,7 @@ ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
|
|||
if (val < 0 || val >= 10)
|
||||
return false;
|
||||
|
||||
*sym_rtrn = ((xkb_keysym_t) val) + '0';
|
||||
*sym_rtrn = XKB_KEY_0 + (xkb_keysym_t) val;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -661,16 +658,17 @@ ExprResolveMod(struct xkb_keymap *keymap, const ExprDef *def,
|
|||
enum mod_type mod_type, xkb_mod_index_t *ndx_rtrn)
|
||||
{
|
||||
xkb_mod_index_t ndx;
|
||||
xkb_atom_t name = def->value.ident;
|
||||
xkb_atom_t name;
|
||||
|
||||
if (def->op != EXPR_IDENT) {
|
||||
if (def->expr.op != EXPR_IDENT) {
|
||||
log_err(keymap->ctx,
|
||||
"Cannot resolve virtual modifier: "
|
||||
"found %s where a virtual modifier name was expected\n",
|
||||
expr_op_type_to_string(def->op));
|
||||
expr_op_type_to_string(def->expr.op));
|
||||
return false;
|
||||
}
|
||||
|
||||
name = def->ident.ident;
|
||||
ndx = ModNameToIndex(keymap, name, mod_type);
|
||||
if (ndx == XKB_MOD_INVALID) {
|
||||
log_err(keymap->ctx,
|
||||
|
|
|
@ -636,13 +636,13 @@ Expr : Expr DIVIDE Expr
|
|||
;
|
||||
|
||||
Term : MINUS Term
|
||||
{ $$ = ExprCreateUnary(EXPR_NEGATE, $2->value_type, $2); }
|
||||
{ $$ = ExprCreateUnary(EXPR_NEGATE, $2->expr.value_type, $2); }
|
||||
| PLUS Term
|
||||
{ $$ = ExprCreateUnary(EXPR_UNARY_PLUS, $2->value_type, $2); }
|
||||
{ $$ = ExprCreateUnary(EXPR_UNARY_PLUS, $2->expr.value_type, $2); }
|
||||
| EXCLAM Term
|
||||
{ $$ = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, $2); }
|
||||
| INVERT Term
|
||||
{ $$ = ExprCreateUnary(EXPR_INVERT, $2->value_type, $2); }
|
||||
{ $$ = ExprCreateUnary(EXPR_INVERT, $2->expr.value_type, $2); }
|
||||
| Lhs
|
||||
{ $$ = $1; }
|
||||
| FieldSpec OPAREN OptExprList CPAREN %prec OPAREN
|
||||
|
|
|
@ -646,11 +646,11 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (value->op != EXPR_KEYSYM_LIST) {
|
||||
if (value->expr.op != EXPR_KEYSYM_LIST) {
|
||||
log_err(info->keymap->ctx,
|
||||
"Expected a list of symbols, found %s; "
|
||||
"Ignoring symbols for group %u of %s\n",
|
||||
expr_op_type_to_string(value->op), ndx + 1,
|
||||
expr_op_type_to_string(value->expr.op), ndx + 1,
|
||||
KeyInfoText(info, keyi));
|
||||
return false;
|
||||
}
|
||||
|
@ -663,7 +663,7 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
|
|||
return false;
|
||||
}
|
||||
|
||||
nLevels = darray_size(value->value.list.symsMapIndex);
|
||||
nLevels = darray_size(value->keysym_list.symsMapIndex);
|
||||
if (darray_size(groupi->levels) < nLevels)
|
||||
darray_resize0(groupi->levels, nLevels);
|
||||
|
||||
|
@ -673,13 +673,13 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
|
|||
unsigned int sym_index;
|
||||
struct xkb_level *leveli = &darray_item(groupi->levels, i);
|
||||
|
||||
sym_index = darray_item(value->value.list.symsMapIndex, i);
|
||||
leveli->num_syms = darray_item(value->value.list.symsNumEntries, i);
|
||||
sym_index = darray_item(value->keysym_list.symsMapIndex, i);
|
||||
leveli->num_syms = darray_item(value->keysym_list.symsNumEntries, i);
|
||||
if (leveli->num_syms > 1)
|
||||
leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms));
|
||||
|
||||
for (j = 0; j < leveli->num_syms; j++) {
|
||||
xkb_keysym_t keysym = darray_item(value->value.list.syms,
|
||||
xkb_keysym_t keysym = darray_item(value->keysym_list.syms,
|
||||
sym_index + j);
|
||||
|
||||
if (leveli->num_syms == 1) {
|
||||
|
@ -718,11 +718,11 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (value->op != EXPR_ACTION_LIST) {
|
||||
if (value->expr.op != EXPR_ACTION_LIST) {
|
||||
log_wsgo(info->keymap->ctx,
|
||||
"Bad expression type (%d) for action list value; "
|
||||
"Ignoring actions for group %u of %s\n",
|
||||
value->op, ndx, KeyInfoText(info, keyi));
|
||||
value->expr.op, ndx, KeyInfoText(info, keyi));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -734,7 +734,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
|
|||
}
|
||||
|
||||
nActs = 0;
|
||||
for (act = value->value.child; act; act = (ExprDef *) act->common.next)
|
||||
for (act = value->unary.child; act; act = (ExprDef *) act->common.next)
|
||||
nActs++;
|
||||
|
||||
if (darray_size(groupi->levels) < nActs)
|
||||
|
@ -742,7 +742,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
|
|||
|
||||
groupi->defined |= GROUP_FIELD_ACTS;
|
||||
|
||||
act = value->value.child;
|
||||
act = value->unary.child;
|
||||
for (i = 0; i < nActs; i++) {
|
||||
toAct = &darray_item(groupi->levels, i).action;
|
||||
|
||||
|
@ -822,7 +822,7 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
|
|||
log_err(info->keymap->ctx,
|
||||
"Expected a virtual modifier mask, found %s; "
|
||||
"Ignoring virtual modifiers definition for key %s\n",
|
||||
expr_op_type_to_string(value->op),
|
||||
expr_op_type_to_string(value->expr.op),
|
||||
KeyInfoText(info, keyi));
|
||||
}
|
||||
}
|
||||
|
@ -1038,7 +1038,7 @@ HandleSymbolsBody(SymbolsInfo *info, VarDef *def, KeyInfo *keyi)
|
|||
ExprDef *arrayNdx;
|
||||
|
||||
for (; def; def = (VarDef *) def->common.next) {
|
||||
if (def->name && def->name->op == EXPR_FIELD_REF) {
|
||||
if (def->name && def->name->expr.op == EXPR_FIELD_REF) {
|
||||
log_err(info->keymap->ctx,
|
||||
"Cannot set a global default value from within a key statement; "
|
||||
"Move statements to the global file scope\n");
|
||||
|
@ -1046,7 +1046,7 @@ HandleSymbolsBody(SymbolsInfo *info, VarDef *def, KeyInfo *keyi)
|
|||
}
|
||||
|
||||
if (!def->name) {
|
||||
if (!def->value || def->value->op == EXPR_KEYSYM_LIST)
|
||||
if (!def->value || def->value->expr.op == EXPR_KEYSYM_LIST)
|
||||
field = "symbols";
|
||||
else
|
||||
field = "actions";
|
||||
|
@ -1157,9 +1157,10 @@ HandleModMapDef(SymbolsInfo *info, ModMapDef *def)
|
|||
for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) {
|
||||
xkb_keysym_t sym;
|
||||
|
||||
if (key->op == EXPR_VALUE && key->value_type == EXPR_TYPE_KEYNAME) {
|
||||
if (key->expr.op == EXPR_VALUE &&
|
||||
key->expr.value_type == EXPR_TYPE_KEYNAME) {
|
||||
tmp.haveSymbol = false;
|
||||
tmp.u.keyName = key->value.keyName;
|
||||
tmp.u.keyName = key->key_name.key_name;
|
||||
}
|
||||
else if (ExprResolveKeySym(ctx, key, &sym)) {
|
||||
tmp.haveSymbol = true;
|
||||
|
|
Loading…
Reference in New Issue