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 "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,

View File

@ -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:

View File

@ -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;

View File

@ -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");

View File

@ -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,

View File

@ -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

View File

@ -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;