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
Ran Benita 2013-12-01 12:08:47 +02:00
parent 068016e4dd
commit 972395b856
7 changed files with 321 additions and 255 deletions

View File

@ -56,18 +56,22 @@
#include "expr.h" #include "expr.h"
#include "action.h" #include "action.h"
static const ExprDef constTrue = { static const ExprBoolean constTrue = {
.common = { .type = STMT_EXPR, .next = NULL }, .expr = {
.op = EXPR_VALUE, .common = { .type = STMT_EXPR, .next = NULL },
.value_type = EXPR_TYPE_BOOLEAN, .op = EXPR_VALUE,
.value = { .set = true }, .value_type = EXPR_TYPE_BOOLEAN,
},
.set = true,
}; };
static const ExprDef constFalse = { static const ExprBoolean constFalse = {
.common = { .type = STMT_EXPR, .next = NULL }, .expr = {
.op = EXPR_VALUE, .common = { .type = STMT_EXPR, .next = NULL },
.value_type = EXPR_TYPE_BOOLEAN, .op = EXPR_VALUE,
.value = { .set = false }, .value_type = EXPR_TYPE_BOOLEAN,
},
.set = false,
}; };
enum action_field { 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, const ExprDef *value, enum xkb_action_flags *flags_inout,
xkb_mod_mask_t *mods_rtrn) xkb_mod_mask_t *mods_rtrn)
{ {
if (value->op == EXPR_IDENT) { if (value->expr.op == EXPR_IDENT) {
const char *valStr; 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") || if (valStr && (istreq(valStr, "usemodmapmods") ||
istreq(valStr, "modmapmods"))) { istreq(valStr, "modmapmods"))) {
@ -367,9 +371,9 @@ CheckGroupField(struct xkb_keymap *keymap, unsigned action,
{ {
const ExprDef *spec; 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; *flags_inout &= ~ACTION_ABSOLUTE_SWITCH;
spec = value->value.child; spec = value->unary.child;
} }
else { else {
*flags_inout |= ACTION_ABSOLUTE_SWITCH; *flags_inout |= ACTION_ABSOLUTE_SWITCH;
@ -380,9 +384,9 @@ CheckGroupField(struct xkb_keymap *keymap, unsigned action,
return ReportMismatch(keymap, action, ACTION_FIELD_GROUP, return ReportMismatch(keymap, action, ACTION_FIELD_GROUP,
"integer (range 1..8)"); "integer (range 1..8)");
if (value->op == EXPR_NEGATE) if (value->expr.op == EXPR_NEGATE)
*grp_rtrn = -*grp_rtrn; *grp_rtrn = -*grp_rtrn;
else if (value->op != EXPR_UNARY_PLUS) else if (value->expr.op != EXPR_UNARY_PLUS)
(*grp_rtrn)--; (*grp_rtrn)--;
return true; return true;
@ -472,7 +476,7 @@ HandleMovePtr(struct xkb_keymap *keymap, union xkb_action *action,
if (field == ACTION_FIELD_X || field == ACTION_FIELD_Y) { if (field == ACTION_FIELD_X || field == ACTION_FIELD_Y) {
int val; 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; absolute = false;
else else
absolute = true; absolute = true;
@ -613,9 +617,10 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
if (array_ndx) if (array_ndx)
return ReportActionNotArray(keymap, action->type, field); 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; act->flags &= ~ACTION_ABSOLUTE_SWITCH;
button = value->value.child; button = value->unary.child;
} }
else { else {
act->flags |= ACTION_ABSOLUTE_SWITCH; act->flags |= ACTION_ABSOLUTE_SWITCH;
@ -639,7 +644,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
return false; return false;
} }
act->value = (value->op == EXPR_NEGATE ? -btn: btn); act->value = (value->expr.op == EXPR_NEGATE ? -btn: btn);
return true; return true;
} }
@ -660,9 +665,10 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
if (array_ndx) if (array_ndx)
return ReportActionNotArray(keymap, action->type, field); 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; act->flags &= ~ACTION_ABSOLUTE_SWITCH;
scrn = value->value.child; scrn = value->unary.child;
} }
else { else {
act->flags |= ACTION_ABSOLUTE_SWITCH; act->flags |= ACTION_ABSOLUTE_SWITCH;
@ -680,7 +686,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
return false; return false;
} }
act->screen = (value->op == EXPR_NEGATE ? -val : val); act->screen = (value->expr.op == EXPR_NEGATE ? -val : val);
return true; return true;
} }
else if (field == ACTION_FIELD_SAME) { else if (field == ACTION_FIELD_SAME) {
@ -861,13 +867,13 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
const char *str; const char *str;
unsigned handler_type; 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", 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; 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)) { if (!stringToAction(str, &handler_type)) {
log_err(keymap->ctx, "Unknown action %s\n", str); log_err(keymap->ctx, "Unknown action %s\n", str);
return false; return false;
@ -885,24 +891,24 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
* particular instance, e.g. "modifiers" and "clearLocks" in: * particular instance, e.g. "modifiers" and "clearLocks" in:
* SetMods(modifiers=Alt,clearLocks); * SetMods(modifiers=Alt,clearLocks);
*/ */
for (arg = def->value.action.args; arg != NULL; for (arg = def->action.args; arg != NULL;
arg = (ExprDef *) arg->common.next) { arg = (ExprDef *) arg->common.next) {
const ExprDef *value; const ExprDef *value;
ExprDef *field, *arrayRtrn; ExprDef *field, *arrayRtrn;
const char *elemRtrn, *fieldRtrn; const char *elemRtrn, *fieldRtrn;
enum action_field fieldNdx; enum action_field fieldNdx;
if (arg->op == EXPR_ASSIGN) { if (arg->expr.op == EXPR_ASSIGN) {
field = arg->value.binary.left; field = arg->binary.left;
value = arg->value.binary.right; value = arg->binary.right;
} }
else if (arg->op == EXPR_NOT || arg->op == EXPR_INVERT) { else if (arg->expr.op == EXPR_NOT || arg->expr.op == EXPR_INVERT) {
field = arg->value.child; field = arg->unary.child;
value = &constFalse; value = (const ExprDef *) &constFalse;
} }
else { else {
field = arg; field = arg;
value = &constTrue; value = (const ExprDef *) &constTrue;
} }
if (!ExprResolveLhs(keymap->ctx, field, &elemRtrn, &fieldRtrn, if (!ExprResolveLhs(keymap->ctx, field, &elemRtrn, &fieldRtrn,

View File

@ -71,16 +71,16 @@ AppendStmt(ParseCommon *to, ParseCommon *append)
} }
static ExprDef * 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) if (!expr)
return NULL; return NULL;
expr->common.type = STMT_EXPR; expr->common.type = STMT_EXPR;
expr->common.next = NULL; expr->common.next = NULL;
expr->op = op; expr->expr.op = op;
expr->value_type = type; expr->expr.value_type = type;
return expr; return expr;
} }
@ -88,11 +88,12 @@ ExprCreate(enum expr_op_type op, enum expr_value_type type)
ExprDef * ExprDef *
ExprCreateString(xkb_atom_t str) 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) if (!expr)
return NULL; return NULL;
expr->value.str = str; expr->string.str = str;
return expr; return expr;
} }
@ -100,11 +101,12 @@ ExprCreateString(xkb_atom_t str)
ExprDef * ExprDef *
ExprCreateInteger(int ival) ExprCreateInteger(int ival)
{ {
ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT); ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT,
sizeof(ExprInteger));
if (!expr) if (!expr)
return NULL; return NULL;
expr->value.ival = ival; expr->integer.ival = ival;
return expr; return expr;
} }
@ -112,11 +114,12 @@ ExprCreateInteger(int ival)
ExprDef * ExprDef *
ExprCreateBoolean(bool set) ExprCreateBoolean(bool set)
{ {
ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN); ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN,
sizeof(ExprBoolean));
if (!expr) if (!expr)
return NULL; return NULL;
expr->value.set = set; expr->boolean.set = set;
return expr; return expr;
} }
@ -124,11 +127,12 @@ ExprCreateBoolean(bool set)
ExprDef * ExprDef *
ExprCreateKeyName(xkb_atom_t key_name) 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) if (!expr)
return NULL; return NULL;
expr->value.keyName = key_name; expr->key_name.key_name = key_name;
return expr; return expr;
} }
@ -136,11 +140,12 @@ ExprCreateKeyName(xkb_atom_t key_name)
ExprDef * ExprDef *
ExprCreateIdent(xkb_atom_t ident) 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) if (!expr)
return NULL; return NULL;
expr->value.ident = ident; expr->ident.ident = ident;
return expr; return expr;
} }
@ -149,11 +154,12 @@ ExprDef *
ExprCreateUnary(enum expr_op_type op, enum expr_value_type type, ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
ExprDef *child) ExprDef *child)
{ {
ExprDef *expr = ExprCreate(op, type); ExprDef *expr = ExprCreate(op, type,
sizeof(ExprUnary));
if (!expr) if (!expr)
return NULL; return NULL;
expr->value.child = child; expr->unary.child = child;
return expr; return expr;
} }
@ -161,17 +167,18 @@ ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
ExprDef * ExprDef *
ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right) 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) if (!expr)
return NULL; return NULL;
if (op == EXPR_ASSIGN || left->value_type == EXPR_TYPE_UNKNOWN) if (op == EXPR_ASSIGN || left->expr.value_type == EXPR_TYPE_UNKNOWN)
expr->value_type = right->value_type; expr->expr.value_type = right->expr.value_type;
else if (left->value_type == right->value_type || else if (left->expr.value_type == right->expr.value_type ||
right->value_type == EXPR_TYPE_UNKNOWN) right->expr.value_type == EXPR_TYPE_UNKNOWN)
expr->value_type = left->value_type; expr->expr.value_type = left->expr.value_type;
expr->value.binary.left = left; expr->binary.left = left;
expr->value.binary.right = right; expr->binary.right = right;
return expr; return expr;
} }
@ -179,12 +186,13 @@ ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
ExprDef * ExprDef *
ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field) 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) if (!expr)
return NULL; return NULL;
expr->value.field.element = element; expr->field_ref.element = element;
expr->value.field.field = field; expr->field_ref.field = field;
return expr; return expr;
} }
@ -192,13 +200,14 @@ ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field)
ExprDef * ExprDef *
ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry) 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) if (!expr)
return NULL; return NULL;
expr->value.array.element = element; expr->array_ref.element = element;
expr->value.array.field = field; expr->array_ref.field = field;
expr->value.array.entry = entry; expr->array_ref.entry = entry;
return expr; return expr;
} }
@ -266,8 +275,8 @@ VarCreate(ExprDef *name, ExprDef *value)
VarDef * VarDef *
BoolVarCreate(xkb_atom_t ident, bool set) BoolVarCreate(xkb_atom_t ident, bool set)
{ {
return VarCreate(ExprCreateIdent(ident), return VarCreate((ExprDef *) ExprCreateIdent(ident),
ExprCreateBoolean(set)); (ExprDef *) ExprCreateBoolean(set));
} }
InterpDef * InterpDef *
@ -385,75 +394,76 @@ LedNameCreate(int ndx, ExprDef *name, bool virtual)
ExprDef * ExprDef *
ActionCreate(xkb_atom_t name, ExprDef *args) ActionCreate(xkb_atom_t name, ExprDef *args)
{ {
ExprDef *act = ExprCreate(EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN); ExprDef *expr = ExprCreate(EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN,
if (!act) sizeof(ExprAction));
if (!expr)
return NULL; return NULL;
act->value.action.name = name; expr->action.name = name;
act->value.action.args = args; expr->action.args = args;
return act; return expr;
} }
ExprDef * ExprDef *
CreateKeysymList(xkb_keysym_t sym) CreateKeysymList(xkb_keysym_t sym)
{ {
ExprDef *def = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS); ExprDef *expr = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS,
if (!def) sizeof(ExprKeysymList));
if (!expr)
return NULL; return NULL;
darray_init(def->value.list.syms); darray_init(expr->keysym_list.syms);
darray_init(def->value.list.symsMapIndex); darray_init(expr->keysym_list.symsMapIndex);
darray_init(def->value.list.symsNumEntries); darray_init(expr->keysym_list.symsNumEntries);
darray_append(def->value.list.syms, sym); darray_append(expr->keysym_list.syms, sym);
darray_append(def->value.list.symsMapIndex, 0); darray_append(expr->keysym_list.symsMapIndex, 0);
darray_append(def->value.list.symsNumEntries, 1); darray_append(expr->keysym_list.symsNumEntries, 1);
return def; return expr;
} }
ExprDef * 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(expr->keysym_list.symsMapIndex, 1);
darray_resize(list->value.list.symsNumEntries, 1); darray_resize(expr->keysym_list.symsNumEntries, 1);
darray_item(list->value.list.symsMapIndex, 0) = 0; darray_item(expr->keysym_list.symsMapIndex, 0) = 0;
darray_item(list->value.list.symsNumEntries, 0) = nLevels; darray_item(expr->keysym_list.symsNumEntries, 0) = nLevels;
return list; return expr;
} }
ExprDef * 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(expr->keysym_list.symsMapIndex, nSyms);
darray_append(list->value.list.symsNumEntries, 1); darray_append(expr->keysym_list.symsNumEntries, 1);
darray_append(list->value.list.syms, sym); darray_append(expr->keysym_list.syms, sym);
return list; return expr;
} }
ExprDef * ExprDef *
AppendMultiKeysymList(ExprDef *list, ExprDef *append) AppendMultiKeysymList(ExprDef *expr, ExprDef *append)
{ {
size_t nSyms = darray_size(list->value.list.syms); size_t nSyms = darray_size(expr->keysym_list.syms);
size_t numEntries = darray_size(append->value.list.syms); size_t numEntries = darray_size(append->keysym_list.syms);
darray_append(list->value.list.symsMapIndex, nSyms); darray_append(expr->keysym_list.symsMapIndex, nSyms);
darray_append(list->value.list.symsNumEntries, numEntries); darray_append(expr->keysym_list.symsNumEntries, numEntries);
darray_append_items(list->value.list.syms, darray_append_items(expr->keysym_list.syms,
darray_mem(append->value.list.syms, 0), darray_mem(append->keysym_list.syms, 0), numEntries);
numEntries);
darray_resize(append->value.list.syms, 0); darray_resize(append->keysym_list.syms, 0);
FreeStmt(&append->common); FreeStmt(&append->common);
return list; return expr;
} }
static void static void
@ -619,13 +629,13 @@ FreeExpr(ExprDef *expr)
if (!expr) if (!expr)
return; return;
switch (expr->op) { switch (expr->expr.op) {
case EXPR_ACTION_LIST: case EXPR_ACTION_LIST:
case EXPR_NEGATE: case EXPR_NEGATE:
case EXPR_UNARY_PLUS: case EXPR_UNARY_PLUS:
case EXPR_NOT: case EXPR_NOT:
case EXPR_INVERT: case EXPR_INVERT:
FreeStmt(&expr->value.child->common); FreeStmt(&expr->unary.child->common);
break; break;
case EXPR_DIVIDE: case EXPR_DIVIDE:
@ -633,22 +643,22 @@ FreeExpr(ExprDef *expr)
case EXPR_SUBTRACT: case EXPR_SUBTRACT:
case EXPR_MULTIPLY: case EXPR_MULTIPLY:
case EXPR_ASSIGN: case EXPR_ASSIGN:
FreeStmt(&expr->value.binary.left->common); FreeStmt(&expr->binary.left->common);
FreeStmt(&expr->value.binary.right->common); FreeStmt(&expr->binary.right->common);
break; break;
case EXPR_ACTION_DECL: case EXPR_ACTION_DECL:
FreeStmt(&expr->value.action.args->common); FreeStmt(&expr->action.args->common);
break; break;
case EXPR_ARRAY_REF: case EXPR_ARRAY_REF:
FreeStmt(&expr->value.array.entry->common); FreeStmt(&expr->array_ref.entry->common);
break; break;
case EXPR_KEYSYM_LIST: case EXPR_KEYSYM_LIST:
darray_free(expr->value.list.syms); darray_free(expr->keysym_list.syms);
darray_free(expr->value.list.symsMapIndex); darray_free(expr->keysym_list.symsMapIndex);
darray_free(expr->value.list.symsNumEntries); darray_free(expr->keysym_list.symsNumEntries);
break; break;
default: default:

View File

@ -158,41 +158,92 @@ typedef struct _IncludeStmt {
struct _IncludeStmt *next_incl; struct _IncludeStmt *next_incl;
} IncludeStmt; } IncludeStmt;
typedef struct _Expr { typedef struct {
ParseCommon common; ParseCommon common;
enum expr_op_type op; enum expr_op_type op;
enum expr_value_type value_type; enum expr_value_type value_type;
union { } ExprCommon;
struct {
struct _Expr *left; typedef union ExprDef ExprDef;
struct _Expr *right;
} binary; typedef struct {
struct { ExprCommon expr;
xkb_atom_t element; xkb_atom_t ident;
xkb_atom_t field; } ExprIdent;
} field;
struct { typedef struct {
xkb_atom_t element; ExprCommon expr;
xkb_atom_t field; xkb_atom_t str;
struct _Expr *entry; } ExprString;
} array;
struct { typedef struct {
xkb_atom_t name; ExprCommon expr;
struct _Expr *args; bool set;
} action; } ExprBoolean;
struct {
darray(xkb_keysym_t) syms; typedef struct {
darray(int) symsMapIndex; ExprCommon expr;
darray(unsigned int) symsNumEntries; int ival;
} list; } ExprInteger;
struct _Expr *child;
xkb_atom_t ident; typedef struct {
xkb_atom_t str; ExprCommon expr;
bool set; xkb_atom_t key_name;
int ival; } ExprKeyName;
xkb_atom_t keyName;
} value; typedef struct {
} ExprDef; 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 { typedef struct {
ParseCommon common; ParseCommon common;

View File

@ -432,19 +432,19 @@ ResolveStateAndPredicate(ExprDef *expr, enum xkb_match_operation *pred_rtrn,
} }
*pred_rtrn = MATCH_EXACTLY; *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, const char *pred_txt = xkb_atom_text(info->keymap->ctx,
expr->value.action.name); expr->action.name);
if (!LookupString(symInterpretMatchMaskNames, pred_txt, pred_rtrn)) { if (!LookupString(symInterpretMatchMaskNames, pred_txt, pred_rtrn)) {
log_err(info->keymap->ctx, log_err(info->keymap->ctx,
"Illegal modifier predicate \"%s\"; Ignored\n", pred_txt); "Illegal modifier predicate \"%s\"; Ignored\n", pred_txt);
return false; 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, const char *pred_txt = xkb_atom_text(info->keymap->ctx,
expr->value.ident); expr->ident.ident);
if (pred_txt && istreq(pred_txt, "any")) { if (pred_txt && istreq(pred_txt, "any")) {
*pred_rtrn = MATCH_ANY; *pred_rtrn = MATCH_ANY;
*mods_rtrn = MOD_REAL_MASK_ALL; *mods_rtrn = MOD_REAL_MASK_ALL;
@ -805,7 +805,7 @@ HandleInterpBody(CompatInfo *info, VarDef *def, SymInterpInfo *si)
ExprDef *arrayNdx; ExprDef *arrayNdx;
for (; def; def = (VarDef *) def->common.next) { 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, log_err(info->keymap->ctx,
"Cannot set a global default value from within an interpret statement; " "Cannot set a global default value from within an interpret statement; "
"Move statements to the global file scope\n"); "Move statements to the global file scope\n");

View File

@ -37,26 +37,26 @@ ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr,
const char **elem_rtrn, const char **field_rtrn, const char **elem_rtrn, const char **field_rtrn,
ExprDef **index_rtrn) ExprDef **index_rtrn)
{ {
switch (expr->op) { switch (expr->expr.op) {
case EXPR_IDENT: case EXPR_IDENT:
*elem_rtrn = NULL; *elem_rtrn = NULL;
*field_rtrn = xkb_atom_text(ctx, expr->value.ident); *field_rtrn = xkb_atom_text(ctx, expr->ident.ident);
*index_rtrn = NULL; *index_rtrn = NULL;
return true; return true;
case EXPR_FIELD_REF: case EXPR_FIELD_REF:
*elem_rtrn = xkb_atom_text(ctx, expr->value.field.element); *elem_rtrn = xkb_atom_text(ctx, expr->field_ref.element);
*field_rtrn = xkb_atom_text(ctx, expr->value.field.field); *field_rtrn = xkb_atom_text(ctx, expr->field_ref.field);
*index_rtrn = NULL; *index_rtrn = NULL;
return true; return true;
case EXPR_ARRAY_REF: case EXPR_ARRAY_REF:
*elem_rtrn = xkb_atom_text(ctx, expr->value.array.element); *elem_rtrn = xkb_atom_text(ctx, expr->array_ref.element);
*field_rtrn = xkb_atom_text(ctx, expr->value.array.field); *field_rtrn = xkb_atom_text(ctx, expr->array_ref.field);
*index_rtrn = expr->value.array.entry; *index_rtrn = expr->array_ref.entry;
return true; return true;
default: default:
break; 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; return false;
} }
@ -127,19 +127,19 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
bool ok = false; bool ok = false;
const char *ident; const char *ident;
switch (expr->op) { switch (expr->expr.op) {
case EXPR_VALUE: case EXPR_VALUE:
if (expr->value_type != EXPR_TYPE_BOOLEAN) { if (expr->expr.value_type != EXPR_TYPE_BOOLEAN) {
log_err(ctx, log_err(ctx,
"Found constant of type %s where boolean was expected\n", "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; return false;
} }
*set_rtrn = expr->value.set; *set_rtrn = expr->boolean.set;
return true; return true;
case EXPR_IDENT: case EXPR_IDENT:
ident = xkb_atom_text(ctx, expr->value.ident); ident = xkb_atom_text(ctx, expr->ident.ident);
if (ident) { if (ident) {
if (istreq(ident, "true") || if (istreq(ident, "true") ||
istreq(ident, "yes") || istreq(ident, "yes") ||
@ -154,14 +154,13 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
return true; return true;
} }
} }
log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n", log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n", ident);
xkb_atom_text(ctx, expr->value.ident));
return false; return false;
case EXPR_FIELD_REF: case EXPR_FIELD_REF:
log_err(ctx, "Default \"%s.%s\" of type boolean is unknown\n", 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->field_ref.element),
xkb_atom_text(ctx, expr->value.field.field)); xkb_atom_text(ctx, expr->field_ref.field));
return false; return false;
case EXPR_INVERT: case EXPR_INVERT:
@ -178,11 +177,12 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_NEGATE: case EXPR_NEGATE:
case EXPR_UNARY_PLUS: case EXPR_UNARY_PLUS:
log_err(ctx, "%s of boolean values not permitted\n", 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; break;
default: 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; break;
} }
@ -194,32 +194,28 @@ ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
xkb_keycode_t *kc) xkb_keycode_t *kc)
{ {
xkb_keycode_t leftRtrn, rightRtrn; xkb_keycode_t leftRtrn, rightRtrn;
ExprDef *left, *right;
switch (expr->op) { switch (expr->expr.op) {
case EXPR_VALUE: case EXPR_VALUE:
if (expr->value_type != EXPR_TYPE_INT) { if (expr->expr.value_type != EXPR_TYPE_INT) {
log_err(ctx, log_err(ctx,
"Found constant of type %s where an int was expected\n", "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; return false;
} }
*kc = (xkb_keycode_t) expr->value.ival; *kc = (xkb_keycode_t) expr->integer.ival;
return true; return true;
case EXPR_ADD: case EXPR_ADD:
case EXPR_SUBTRACT: case EXPR_SUBTRACT:
case EXPR_MULTIPLY: case EXPR_MULTIPLY:
case EXPR_DIVIDE: case EXPR_DIVIDE:
left = expr->value.binary.left; if (!ExprResolveKeyCode(ctx, expr->binary.left, &leftRtrn) ||
right = expr->value.binary.right; !ExprResolveKeyCode(ctx, expr->binary.right, &rightRtrn))
if (!ExprResolveKeyCode(ctx, left, &leftRtrn) ||
!ExprResolveKeyCode(ctx, right, &rightRtrn))
return false; return false;
switch (expr->op) { switch (expr->expr.op) {
case EXPR_ADD: case EXPR_ADD:
*kc = leftRtrn + rightRtrn; *kc = leftRtrn + rightRtrn;
break; break;
@ -245,19 +241,18 @@ ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
return true; return true;
case EXPR_NEGATE: case EXPR_NEGATE:
left = expr->value.child; if (!ExprResolveKeyCode(ctx, expr->unary.child, &leftRtrn))
if (!ExprResolveKeyCode(ctx, left, &leftRtrn))
return false; return false;
*kc = ~leftRtrn; *kc = ~leftRtrn;
return true; return true;
case EXPR_UNARY_PLUS: case EXPR_UNARY_PLUS:
left = expr->value.child; return ExprResolveKeyCode(ctx, expr->unary.child, kc);
return ExprResolveKeyCode(ctx, left, kc);
default: 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; break;
} }
@ -284,25 +279,25 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
unsigned u; unsigned u;
ExprDef *left, *right; ExprDef *left, *right;
switch (expr->op) { switch (expr->expr.op) {
case EXPR_VALUE: case EXPR_VALUE:
if (expr->value_type != EXPR_TYPE_INT) { if (expr->expr.value_type != EXPR_TYPE_INT) {
log_err(ctx, log_err(ctx,
"Found constant of type %s where an int was expected\n", "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; return false;
} }
*val_rtrn = expr->value.ival; *val_rtrn = expr->integer.ival;
return true; return true;
case EXPR_IDENT: case EXPR_IDENT:
if (lookup) 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) if (!ok)
log_err(ctx, "Identifier \"%s\" of type int is unknown\n", 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 else
*val_rtrn = (int) u; *val_rtrn = (int) u;
@ -310,21 +305,21 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_FIELD_REF: case EXPR_FIELD_REF:
log_err(ctx, "Default \"%s.%s\" of type int is unknown\n", 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->field_ref.element),
xkb_atom_text(ctx, expr->value.field.field)); xkb_atom_text(ctx, expr->field_ref.field));
return false; return false;
case EXPR_ADD: case EXPR_ADD:
case EXPR_SUBTRACT: case EXPR_SUBTRACT:
case EXPR_MULTIPLY: case EXPR_MULTIPLY:
case EXPR_DIVIDE: case EXPR_DIVIDE:
left = expr->value.binary.left; left = expr->binary.left;
right = expr->value.binary.right; right = expr->binary.right;
if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv) || if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv) ||
!ExprResolveIntegerLookup(ctx, right, &r, lookup, lookupPriv)) !ExprResolveIntegerLookup(ctx, right, &r, lookup, lookupPriv))
return false; return false;
switch (expr->op) { switch (expr->expr.op) {
case EXPR_ADD: case EXPR_ADD:
*val_rtrn = l + r; *val_rtrn = l + r;
break; break;
@ -357,20 +352,21 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_INVERT: case EXPR_INVERT:
case EXPR_NEGATE: case EXPR_NEGATE:
left = expr->value.child; left = expr->unary.child;
if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv)) if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv))
return false; return false;
*val_rtrn = (expr->op == EXPR_NEGATE ? -l : ~l); *val_rtrn = (expr->expr.op == EXPR_NEGATE ? -l : ~l);
return true; return true;
case EXPR_UNARY_PLUS: case EXPR_UNARY_PLUS:
left = expr->value.child; left = expr->unary.child;
return ExprResolveIntegerLookup(ctx, left, val_rtrn, lookup, return ExprResolveIntegerLookup(ctx, left, val_rtrn, lookup,
lookupPriv); lookupPriv);
default: 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; break;
} }
@ -445,26 +441,26 @@ bool
ExprResolveString(struct xkb_context *ctx, const ExprDef *expr, ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
xkb_atom_t *val_rtrn) xkb_atom_t *val_rtrn)
{ {
switch (expr->op) { switch (expr->expr.op) {
case EXPR_VALUE: 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", 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; return false;
} }
*val_rtrn = expr->value.str; *val_rtrn = expr->string.str;
return true; return true;
case EXPR_IDENT: case EXPR_IDENT:
log_err(ctx, "Identifier \"%s\" of type string not found\n", 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; return false;
case EXPR_FIELD_REF: case EXPR_FIELD_REF:
log_err(ctx, "Default \"%s.%s\" of type string not found\n", 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->field_ref.element),
xkb_atom_text(ctx, expr->value.field.field)); xkb_atom_text(ctx, expr->field_ref.field));
return false; return false;
case EXPR_ADD: case EXPR_ADD:
@ -477,11 +473,12 @@ ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_NOT: case EXPR_NOT:
case EXPR_UNARY_PLUS: case EXPR_UNARY_PLUS:
log_err(ctx, "%s of strings not permitted\n", 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; return false;
default: 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; break;
} }
return false; return false;
@ -491,16 +488,16 @@ bool
ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr, ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr,
unsigned int *val_rtrn, const LookupEntry *values) 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", 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; return false;
} }
if (!SimpleLookup(ctx, values, expr->value.ident, EXPR_TYPE_INT, if (!SimpleLookup(ctx, values, expr->ident.ident, EXPR_TYPE_INT,
val_rtrn)) { val_rtrn)) {
log_err(ctx, "Illegal identifier %s; expected one of:\n", 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) while (values && values->name)
{ {
log_err(ctx, "\t%s\n", 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; ExprDef *left, *right;
const char *bogus = NULL; const char *bogus = NULL;
switch (expr->op) { switch (expr->expr.op) {
case EXPR_VALUE: case EXPR_VALUE:
if (expr->value_type != EXPR_TYPE_INT) { if (expr->expr.value_type != EXPR_TYPE_INT) {
log_err(ctx, log_err(ctx,
"Found constant of type %s where a mask was expected\n", "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; return false;
} }
*val_rtrn = (unsigned int) expr->value.ival; *val_rtrn = (unsigned int) expr->integer.ival;
return true; return true;
case EXPR_IDENT: 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); val_rtrn);
if (!ok) if (!ok)
log_err(ctx, "Identifier \"%s\" of type int is unknown\n", 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; return ok;
case EXPR_FIELD_REF: case EXPR_FIELD_REF:
log_err(ctx, "Default \"%s.%s\" of type int is unknown\n", 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->field_ref.element),
xkb_atom_text(ctx, expr->value.field.field)); xkb_atom_text(ctx, expr->field_ref.field));
return false; return false;
case EXPR_ARRAY_REF: case EXPR_ARRAY_REF:
@ -563,13 +560,13 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_SUBTRACT: case EXPR_SUBTRACT:
case EXPR_MULTIPLY: case EXPR_MULTIPLY:
case EXPR_DIVIDE: case EXPR_DIVIDE:
left = expr->value.binary.left; left = expr->binary.left;
right = expr->value.binary.right; right = expr->binary.right;
if (!ExprResolveMaskLookup(ctx, left, &l, lookup, lookupPriv) || if (!ExprResolveMaskLookup(ctx, left, &l, lookup, lookupPriv) ||
!ExprResolveMaskLookup(ctx, right, &r, lookup, lookupPriv)) !ExprResolveMaskLookup(ctx, right, &r, lookup, lookupPriv))
return false; return false;
switch (expr->op) { switch (expr->expr.op) {
case EXPR_ADD: case EXPR_ADD:
*val_rtrn = l | r; *val_rtrn = l | r;
break; break;
@ -579,7 +576,7 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_MULTIPLY: case EXPR_MULTIPLY:
case EXPR_DIVIDE: case EXPR_DIVIDE:
log_err(ctx, "Cannot %s masks; Illegal operation ignored\n", 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; return false;
default: default:
break; break;
@ -592,7 +589,7 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
break; break;
case EXPR_INVERT: case EXPR_INVERT:
left = expr->value.child; left = expr->unary.child;
if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv)) if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
return false; return false;
@ -602,14 +599,15 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_UNARY_PLUS: case EXPR_UNARY_PLUS:
case EXPR_NEGATE: case EXPR_NEGATE:
case EXPR_NOT: case EXPR_NOT:
left = expr->value.child; left = expr->unary.child;
if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv)) if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
log_err(ctx, "The %s operator cannot be used with a mask\n", log_err(ctx, "The %s operator cannot be used with a mask\n",
(expr->op == EXPR_NEGATE ? "-" : "!")); (expr->expr.op == EXPR_NEGATE ? "-" : "!"));
return false; return false;
default: 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; break;
} }
@ -638,9 +636,8 @@ ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
{ {
int val; int val;
if (expr->op == EXPR_IDENT) { if (expr->expr.op == EXPR_IDENT) {
const char *str; const char *str = xkb_atom_text(ctx, expr->ident.ident);
str = xkb_atom_text(ctx, expr->value.ident);
*sym_rtrn = xkb_keysym_from_name(str, 0); *sym_rtrn = xkb_keysym_from_name(str, 0);
if (*sym_rtrn != XKB_KEY_NoSymbol) if (*sym_rtrn != XKB_KEY_NoSymbol)
return true; return true;
@ -652,7 +649,7 @@ ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
if (val < 0 || val >= 10) if (val < 0 || val >= 10)
return false; return false;
*sym_rtrn = ((xkb_keysym_t) val) + '0'; *sym_rtrn = XKB_KEY_0 + (xkb_keysym_t) val;
return true; 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) enum mod_type mod_type, xkb_mod_index_t *ndx_rtrn)
{ {
xkb_mod_index_t ndx; 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, log_err(keymap->ctx,
"Cannot resolve virtual modifier: " "Cannot resolve virtual modifier: "
"found %s where a virtual modifier name was expected\n", "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; return false;
} }
name = def->ident.ident;
ndx = ModNameToIndex(keymap, name, mod_type); ndx = ModNameToIndex(keymap, name, mod_type);
if (ndx == XKB_MOD_INVALID) { if (ndx == XKB_MOD_INVALID) {
log_err(keymap->ctx, log_err(keymap->ctx,

View File

@ -636,13 +636,13 @@ Expr : Expr DIVIDE Expr
; ;
Term : MINUS Term Term : MINUS Term
{ $$ = ExprCreateUnary(EXPR_NEGATE, $2->value_type, $2); } { $$ = ExprCreateUnary(EXPR_NEGATE, $2->expr.value_type, $2); }
| PLUS Term | PLUS Term
{ $$ = ExprCreateUnary(EXPR_UNARY_PLUS, $2->value_type, $2); } { $$ = ExprCreateUnary(EXPR_UNARY_PLUS, $2->expr.value_type, $2); }
| EXCLAM Term | EXCLAM Term
{ $$ = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, $2); } { $$ = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, $2); }
| INVERT Term | INVERT Term
{ $$ = ExprCreateUnary(EXPR_INVERT, $2->value_type, $2); } { $$ = ExprCreateUnary(EXPR_INVERT, $2->expr.value_type, $2); }
| Lhs | Lhs
{ $$ = $1; } { $$ = $1; }
| FieldSpec OPAREN OptExprList CPAREN %prec OPAREN | FieldSpec OPAREN OptExprList CPAREN %prec OPAREN

View File

@ -646,11 +646,11 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
return true; return true;
} }
if (value->op != EXPR_KEYSYM_LIST) { if (value->expr.op != EXPR_KEYSYM_LIST) {
log_err(info->keymap->ctx, log_err(info->keymap->ctx,
"Expected a list of symbols, found %s; " "Expected a list of symbols, found %s; "
"Ignoring symbols for group %u of %s\n", "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)); KeyInfoText(info, keyi));
return false; return false;
} }
@ -663,7 +663,7 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
return false; return false;
} }
nLevels = darray_size(value->value.list.symsMapIndex); nLevels = darray_size(value->keysym_list.symsMapIndex);
if (darray_size(groupi->levels) < nLevels) if (darray_size(groupi->levels) < nLevels)
darray_resize0(groupi->levels, nLevels); darray_resize0(groupi->levels, nLevels);
@ -673,13 +673,13 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
unsigned int sym_index; unsigned int sym_index;
struct xkb_level *leveli = &darray_item(groupi->levels, i); struct xkb_level *leveli = &darray_item(groupi->levels, i);
sym_index = darray_item(value->value.list.symsMapIndex, i); sym_index = darray_item(value->keysym_list.symsMapIndex, i);
leveli->num_syms = darray_item(value->value.list.symsNumEntries, i); leveli->num_syms = darray_item(value->keysym_list.symsNumEntries, i);
if (leveli->num_syms > 1) if (leveli->num_syms > 1)
leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms)); leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms));
for (j = 0; j < leveli->num_syms; j++) { 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); sym_index + j);
if (leveli->num_syms == 1) { if (leveli->num_syms == 1) {
@ -718,11 +718,11 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
return true; return true;
} }
if (value->op != EXPR_ACTION_LIST) { if (value->expr.op != EXPR_ACTION_LIST) {
log_wsgo(info->keymap->ctx, log_wsgo(info->keymap->ctx,
"Bad expression type (%d) for action list value; " "Bad expression type (%d) for action list value; "
"Ignoring actions for group %u of %s\n", "Ignoring actions for group %u of %s\n",
value->op, ndx, KeyInfoText(info, keyi)); value->expr.op, ndx, KeyInfoText(info, keyi));
return false; return false;
} }
@ -734,7 +734,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
} }
nActs = 0; 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++; nActs++;
if (darray_size(groupi->levels) < nActs) if (darray_size(groupi->levels) < nActs)
@ -742,7 +742,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
groupi->defined |= GROUP_FIELD_ACTS; groupi->defined |= GROUP_FIELD_ACTS;
act = value->value.child; act = value->unary.child;
for (i = 0; i < nActs; i++) { for (i = 0; i < nActs; i++) {
toAct = &darray_item(groupi->levels, i).action; toAct = &darray_item(groupi->levels, i).action;
@ -822,7 +822,7 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
log_err(info->keymap->ctx, log_err(info->keymap->ctx,
"Expected a virtual modifier mask, found %s; " "Expected a virtual modifier mask, found %s; "
"Ignoring virtual modifiers definition for key %s\n", "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)); KeyInfoText(info, keyi));
} }
} }
@ -1038,7 +1038,7 @@ HandleSymbolsBody(SymbolsInfo *info, VarDef *def, KeyInfo *keyi)
ExprDef *arrayNdx; ExprDef *arrayNdx;
for (; def; def = (VarDef *) def->common.next) { 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, log_err(info->keymap->ctx,
"Cannot set a global default value from within a key statement; " "Cannot set a global default value from within a key statement; "
"Move statements to the global file scope\n"); "Move statements to the global file scope\n");
@ -1046,7 +1046,7 @@ HandleSymbolsBody(SymbolsInfo *info, VarDef *def, KeyInfo *keyi)
} }
if (!def->name) { if (!def->name) {
if (!def->value || def->value->op == EXPR_KEYSYM_LIST) if (!def->value || def->value->expr.op == EXPR_KEYSYM_LIST)
field = "symbols"; field = "symbols";
else else
field = "actions"; field = "actions";
@ -1157,9 +1157,10 @@ HandleModMapDef(SymbolsInfo *info, ModMapDef *def)
for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) { for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) {
xkb_keysym_t sym; 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.haveSymbol = false;
tmp.u.keyName = key->value.keyName; tmp.u.keyName = key->key_name.key_name;
} }
else if (ExprResolveKeySym(ctx, key, &sym)) { else if (ExprResolveKeySym(ctx, key, &sym)) {
tmp.haveSymbol = true; tmp.haveSymbol = true;