From 972395b8569bd80930048c9fc594a5b5fbf74b4a Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sun, 1 Dec 2013 12:08:47 +0200 Subject: [PATCH] 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 --- src/xkbcomp/action.c | 74 +++++++++-------- src/xkbcomp/ast-build.c | 168 ++++++++++++++++++++------------------- src/xkbcomp/ast.h | 115 +++++++++++++++++++-------- src/xkbcomp/compat.c | 12 +-- src/xkbcomp/expr.c | 170 ++++++++++++++++++++-------------------- src/xkbcomp/parser.y | 6 +- src/xkbcomp/symbols.c | 31 ++++---- 7 files changed, 321 insertions(+), 255 deletions(-) diff --git a/src/xkbcomp/action.c b/src/xkbcomp/action.c index 37b9338..fed108f 100644 --- a/src/xkbcomp/action.c +++ b/src/xkbcomp/action.c @@ -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, diff --git a/src/xkbcomp/ast-build.c b/src/xkbcomp/ast-build.c index 9f429d9..8e0b0c6 100644 --- a/src/xkbcomp/ast-build.c +++ b/src/xkbcomp/ast-build.c @@ -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: diff --git a/src/xkbcomp/ast.h b/src/xkbcomp/ast.h index c63b796..36f777a 100644 --- a/src/xkbcomp/ast.h +++ b/src/xkbcomp/ast.h @@ -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; diff --git a/src/xkbcomp/compat.c b/src/xkbcomp/compat.c index 0775a98..fffb2d3 100644 --- a/src/xkbcomp/compat.c +++ b/src/xkbcomp/compat.c @@ -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"); diff --git a/src/xkbcomp/expr.c b/src/xkbcomp/expr.c index 227f351..ba71208 100644 --- a/src/xkbcomp/expr.c +++ b/src/xkbcomp/expr.c @@ -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, diff --git a/src/xkbcomp/parser.y b/src/xkbcomp/parser.y index 272562f..167af8e 100644 --- a/src/xkbcomp/parser.y +++ b/src/xkbcomp/parser.y @@ -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 diff --git a/src/xkbcomp/symbols.c b/src/xkbcomp/symbols.c index 075516d..36d87b8 100644 --- a/src/xkbcomp/symbols.c +++ b/src/xkbcomp/symbols.c @@ -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;