From e39621b822e0f5cd3e875b32e13455074f224f6e Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Fri, 24 Jan 2025 20:03:55 +0200 Subject: [PATCH] WIP: xkbcomp: allocate AST nodes using bump allocator bench/rulescomp before: total heap usage: 10,980,536 allocs, 10,980,536 frees, 490,563,213 bytes allocated compiled 1000 keymaps in 2.300165s after: total heap usage: 4,647,536 allocs, 4,647,536 frees, 538,021,213 bytes allocated compiled 1000 keymaps in 1.949309s Signed-off-by: Ran Benita --- src/xkbcomp/ast-build.c | 324 ++++++++++--------------------------- src/xkbcomp/ast-build.h | 65 ++++---- src/xkbcomp/ast.h | 1 + src/xkbcomp/compat.c | 12 +- src/xkbcomp/include.c | 22 ++- src/xkbcomp/include.h | 9 +- src/xkbcomp/keycodes.c | 12 +- src/xkbcomp/parser-priv.h | 2 +- src/xkbcomp/parser.y | 144 ++++++++--------- src/xkbcomp/scanner.c | 9 +- src/xkbcomp/symbols.c | 11 +- src/xkbcomp/types.c | 12 +- src/xkbcomp/xkbcomp-priv.h | 10 +- src/xkbcomp/xkbcomp.c | 34 ++-- 14 files changed, 249 insertions(+), 418 deletions(-) diff --git a/src/xkbcomp/ast-build.c b/src/xkbcomp/ast-build.c index 9328baf7..11b4acdf 100644 --- a/src/xkbcomp/ast-build.c +++ b/src/xkbcomp/ast-build.c @@ -51,6 +51,7 @@ * Ran Benita */ +#include "bump.h" #include "config.h" #include "xkbcomp-priv.h" @@ -58,9 +59,9 @@ #include "include.h" static ExprDef * -ExprCreate(enum expr_op_type op, enum expr_value_type type, size_t size) +ExprCreate(struct bump *bump, enum expr_op_type op, enum expr_value_type type, size_t size) { - ExprDef *expr = malloc(size); + ExprDef *expr = bump_alloc(bump, size); if (!expr) return NULL; @@ -73,9 +74,9 @@ ExprCreate(enum expr_op_type op, enum expr_value_type type, size_t size) } ExprDef * -ExprCreateString(xkb_atom_t str) +ExprCreateString(struct bump *bump, xkb_atom_t str) { - ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING, sizeof(ExprString)); + ExprDef *expr = ExprCreate(bump, EXPR_VALUE, EXPR_TYPE_STRING, sizeof(ExprString)); if (!expr) return NULL; expr->string.str = str; @@ -83,9 +84,9 @@ ExprCreateString(xkb_atom_t str) } ExprDef * -ExprCreateInteger(int ival) +ExprCreateInteger(struct bump *bump, int ival) { - ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT, sizeof(ExprInteger)); + ExprDef *expr = ExprCreate(bump, EXPR_VALUE, EXPR_TYPE_INT, sizeof(ExprInteger)); if (!expr) return NULL; expr->integer.ival = ival; @@ -93,18 +94,18 @@ ExprCreateInteger(int ival) } ExprDef * -ExprCreateFloat(void) +ExprCreateFloat(struct bump *bump) { - ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_FLOAT, sizeof(ExprFloat)); + ExprDef *expr = ExprCreate(bump, EXPR_VALUE, EXPR_TYPE_FLOAT, sizeof(ExprFloat)); if (!expr) return NULL; return expr; } ExprDef * -ExprCreateBoolean(bool set) +ExprCreateBoolean(struct bump *bump, bool set) { - ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN, sizeof(ExprBoolean)); + ExprDef *expr = ExprCreate(bump, EXPR_VALUE, EXPR_TYPE_BOOLEAN, sizeof(ExprBoolean)); if (!expr) return NULL; expr->boolean.set = set; @@ -112,9 +113,9 @@ ExprCreateBoolean(bool set) } ExprDef * -ExprCreateKeyName(xkb_atom_t key_name) +ExprCreateKeyName(struct bump *bump, xkb_atom_t key_name) { - ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME, sizeof(ExprKeyName)); + ExprDef *expr = ExprCreate(bump, EXPR_VALUE, EXPR_TYPE_KEYNAME, sizeof(ExprKeyName)); if (!expr) return NULL; expr->key_name.key_name = key_name; @@ -122,9 +123,9 @@ ExprCreateKeyName(xkb_atom_t key_name) } ExprDef * -ExprCreateIdent(xkb_atom_t ident) +ExprCreateIdent(struct bump *bump, xkb_atom_t ident) { - ExprDef *expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN, sizeof(ExprIdent)); + ExprDef *expr = ExprCreate(bump, EXPR_IDENT, EXPR_TYPE_UNKNOWN, sizeof(ExprIdent)); if (!expr) return NULL; expr->ident.ident = ident; @@ -132,10 +133,10 @@ ExprCreateIdent(xkb_atom_t ident) } ExprDef * -ExprCreateUnary(enum expr_op_type op, enum expr_value_type type, +ExprCreateUnary(struct bump *bump, enum expr_op_type op, enum expr_value_type type, ExprDef *child) { - ExprDef *expr = ExprCreate(op, type, sizeof(ExprUnary)); + ExprDef *expr = ExprCreate(bump, op, type, sizeof(ExprUnary)); if (!expr) return NULL; expr->unary.child = child; @@ -143,9 +144,9 @@ ExprCreateUnary(enum expr_op_type op, enum expr_value_type type, } ExprDef * -ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right) +ExprCreateBinary(struct bump *bump, enum expr_op_type op, ExprDef *left, ExprDef *right) { - ExprDef *expr = ExprCreate(op, EXPR_TYPE_UNKNOWN, sizeof(ExprBinary)); + ExprDef *expr = ExprCreate(bump, op, EXPR_TYPE_UNKNOWN, sizeof(ExprBinary)); if (!expr) return NULL; @@ -161,9 +162,9 @@ ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right) } ExprDef * -ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field) +ExprCreateFieldRef(struct bump *bump, xkb_atom_t element, xkb_atom_t field) { - ExprDef *expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN, sizeof(ExprFieldRef)); + ExprDef *expr = ExprCreate(bump, EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN, sizeof(ExprFieldRef)); if (!expr) return NULL; expr->field_ref.element = element; @@ -172,9 +173,9 @@ ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field) } ExprDef * -ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry) +ExprCreateArrayRef(struct bump *bump, xkb_atom_t element, xkb_atom_t field, ExprDef *entry) { - ExprDef *expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN, sizeof(ExprArrayRef)); + ExprDef *expr = ExprCreate(bump, EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN, sizeof(ExprArrayRef)); if (!expr) return NULL; expr->array_ref.element = element; @@ -184,15 +185,15 @@ ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry) } ExprDef * -ExprEmptyList(void) +ExprEmptyList(struct bump *bump) { - return ExprCreate(EXPR_EMPTY_LIST, EXPR_TYPE_UNKNOWN, sizeof(ExprCommon)); + return ExprCreate(bump, EXPR_EMPTY_LIST, EXPR_TYPE_UNKNOWN, sizeof(ExprCommon)); } ExprDef * -ExprCreateAction(xkb_atom_t name, ExprDef *args) +ExprCreateAction(struct bump *bump, xkb_atom_t name, ExprDef *args) { - ExprDef *expr = ExprCreate(EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN, sizeof(ExprAction)); + ExprDef *expr = ExprCreate(bump, EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN, sizeof(ExprAction)); if (!expr) return NULL; expr->action.name = name; @@ -201,9 +202,9 @@ ExprCreateAction(xkb_atom_t name, ExprDef *args) } ExprDef * -ExprCreateActionList(ExprDef *actions) +ExprCreateActionList(struct bump *bump, ExprDef *actions) { - ExprDef *expr = ExprCreate(EXPR_ACTION_LIST, EXPR_TYPE_ACTIONS, sizeof(ExprActionList)); + ExprDef *expr = ExprCreate(bump, EXPR_ACTION_LIST, EXPR_TYPE_ACTIONS, sizeof(ExprActionList)); if (!expr) return NULL; expr->actions.actions = actions; @@ -211,14 +212,13 @@ ExprCreateActionList(ExprDef *actions) } ExprDef * -ExprCreateKeysymList(xkb_keysym_t sym) +ExprCreateKeysymList(struct bump *bump, xkb_keysym_t sym) { - ExprDef *expr = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS, sizeof(ExprKeysymList)); + ExprDef *expr = ExprCreate(bump, EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS, sizeof(ExprKeysymList)); if (!expr) return NULL; - expr->keysym_list.syms = malloc(sizeof(*expr->keysym_list.syms)); + expr->keysym_list.syms = bump_alloc(bump, sizeof(*expr->keysym_list.syms)); if (!expr->keysym_list.syms) { - FreeStmt(&expr->common); return NULL; } expr->keysym_list.num_syms = 1; @@ -227,18 +227,21 @@ ExprCreateKeysymList(xkb_keysym_t sym) } ExprDef * -ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym) +ExprAppendKeysymList(struct bump *bump, ExprDef *expr, xkb_keysym_t sym) { ExprKeysymList *kl = &expr->keysym_list; - kl->syms = realloc(kl->syms, (kl->num_syms + 1) * sizeof(*kl->syms)); + xkb_keysym_t *old = kl->syms; + kl->syms = bump_alloc(bump, (kl->num_syms + 1) * sizeof(*kl->syms)); + for (unsigned i = 0; i < kl->num_syms; i++) + kl->syms[i] = old[i]; kl->syms[kl->num_syms++] = sym; return expr; } KeycodeDef * -KeycodeCreate(xkb_atom_t name, int64_t value) +KeycodeCreate(struct bump *bump, xkb_atom_t name, int64_t value) { - KeycodeDef *def = malloc(sizeof(*def)); + KeycodeDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -251,9 +254,9 @@ KeycodeCreate(xkb_atom_t name, int64_t value) } KeyAliasDef * -KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real) +KeyAliasCreate(struct bump *bump, xkb_atom_t alias, xkb_atom_t real) { - KeyAliasDef *def = malloc(sizeof(*def)); + KeyAliasDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -266,9 +269,9 @@ KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real) } VModDef * -VModCreate(xkb_atom_t name, ExprDef *value) +VModCreate(struct bump *bump, xkb_atom_t name, ExprDef *value) { - VModDef *def = malloc(sizeof(*def)); + VModDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -281,9 +284,9 @@ VModCreate(xkb_atom_t name, ExprDef *value) } VarDef * -VarCreate(ExprDef *name, ExprDef *value) +VarCreate(struct bump *bump, ExprDef *name, ExprDef *value) { - VarDef *def = malloc(sizeof(*def)); + VarDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -296,29 +299,26 @@ VarCreate(ExprDef *name, ExprDef *value) } VarDef * -BoolVarCreate(xkb_atom_t ident, bool set) +BoolVarCreate(struct bump *bump, xkb_atom_t ident, bool set) { ExprDef *name, *value; VarDef *def; - if (!(name = ExprCreateIdent(ident))) { + if (!(name = ExprCreateIdent(bump, ident))) { return NULL; } - if (!(value = ExprCreateBoolean(set))) { - FreeStmt((ParseCommon *) name); + if (!(value = ExprCreateBoolean(bump, set))) { return NULL; } - if (!(def = VarCreate(name, value))) { - FreeStmt((ParseCommon *) name); - FreeStmt((ParseCommon *) value); + if (!(def = VarCreate(bump, name, value))) { return NULL; } return def; } InterpDef * -InterpCreate(xkb_keysym_t sym, ExprDef *match) +InterpCreate(struct bump *bump, xkb_keysym_t sym, ExprDef *match) { - InterpDef *def = malloc(sizeof(*def)); + InterpDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -332,9 +332,9 @@ InterpCreate(xkb_keysym_t sym, ExprDef *match) } KeyTypeDef * -KeyTypeCreate(xkb_atom_t name, VarDef *body) +KeyTypeCreate(struct bump *bump, xkb_atom_t name, VarDef *body) { - KeyTypeDef *def = malloc(sizeof(*def)); + KeyTypeDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -348,9 +348,9 @@ KeyTypeCreate(xkb_atom_t name, VarDef *body) } SymbolsDef * -SymbolsCreate(xkb_atom_t keyName, VarDef *symbols) +SymbolsCreate(struct bump *bump, xkb_atom_t keyName, VarDef *symbols) { - SymbolsDef *def = malloc(sizeof(*def)); + SymbolsDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -364,9 +364,9 @@ SymbolsCreate(xkb_atom_t keyName, VarDef *symbols) } GroupCompatDef * -GroupCompatCreate(unsigned group, ExprDef *val) +GroupCompatCreate(struct bump *bump, unsigned group, ExprDef *val) { - GroupCompatDef *def = malloc(sizeof(*def)); + GroupCompatDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -380,9 +380,9 @@ GroupCompatCreate(unsigned group, ExprDef *val) } ModMapDef * -ModMapCreate(xkb_atom_t modifier, ExprDef *keys) +ModMapCreate(struct bump *bump, xkb_atom_t modifier, ExprDef *keys) { - ModMapDef *def = malloc(sizeof(*def)); + ModMapDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -396,9 +396,9 @@ ModMapCreate(xkb_atom_t modifier, ExprDef *keys) } LedMapDef * -LedMapCreate(xkb_atom_t name, VarDef *body) +LedMapCreate(struct bump *bump, xkb_atom_t name, VarDef *body) { - LedMapDef *def = malloc(sizeof(*def)); + LedMapDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -412,9 +412,9 @@ LedMapCreate(xkb_atom_t name, VarDef *body) } LedNameDef * -LedNameCreate(unsigned ndx, ExprDef *name, bool virtual) +LedNameCreate(struct bump *bump, unsigned ndx, ExprDef *name, bool virtual) { - LedNameDef *def = malloc(sizeof(*def)); + LedNameDef *def = bump_alloc(bump, sizeof(*def)); if (!def) return NULL; @@ -428,11 +428,8 @@ LedNameCreate(unsigned ndx, ExprDef *name, bool virtual) return def; } -static void -FreeInclude(IncludeStmt *incl); - IncludeStmt * -IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge) +IncludeCreate(struct bump *bump, struct xkb_context *ctx, char *str, enum merge_mode merge) { IncludeStmt *incl, *first; char *stmt, *tmp; @@ -440,12 +437,12 @@ IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge) incl = first = NULL; tmp = str; - stmt = strdup_safe(str); + stmt = str ? bump_strdup(bump, str) : NULL; while (tmp && *tmp) { char *file = NULL, *map = NULL, *extra_data = NULL; - if (!ParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data)) + if (!ParseIncludeMap(bump, &tmp, &file, &map, &nextop, &extra_data)) goto err; /* @@ -455,23 +452,17 @@ IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge) * appropriate section to deal with the empty group. */ if (isempty(file)) { - free(file); - free(map); - free(extra_data); continue; } if (first == NULL) { - first = incl = malloc(sizeof(*first)); + first = incl = bump_alloc(bump, sizeof(*first)); } else { - incl->next_incl = malloc(sizeof(*first)); + incl->next_incl = bump_alloc(bump, sizeof(*first)); incl = incl->next_incl; } if (!incl) { - free(file); - free(map); - free(extra_data); break; } @@ -492,32 +483,34 @@ IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge) if (first) first->stmt = stmt; - else - free(stmt); return first; err: log_err(ctx, XKB_ERROR_INVALID_INCLUDE_STATEMENT, "Illegal include statement \"%s\"; Ignored\n", stmt); - FreeInclude(first); - free(stmt); return NULL; } XkbFile * -XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs, - enum xkb_map_flags flags) +XkbFileCreate(struct bump *bump, enum xkb_file_type type, char *name, + ParseCommon *defs, enum xkb_map_flags flags) { XkbFile *file; - file = calloc(1, sizeof(*file)); + file = bump_alloc(bump, sizeof(*file)); if (!file) return NULL; + memset(file, 0, sizeof(*file)); XkbEscapeMapName(name); + file->bump = bump; file->file_type = type; - file->name = name ? name : strdup("(unnamed)"); + if (name) { + file->name = name; + } else { + file->name = bump_strdup(bump, "(unnamed)"); + } file->defs = defs; file->flags = flags; @@ -525,7 +518,7 @@ XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs, } XkbFile * -XkbFileFromComponents(struct xkb_context *ctx, +XkbFileFromComponents(struct bump *bump, struct xkb_context *ctx, const struct xkb_component_names *kkctgs) { char *const components[] = { @@ -538,13 +531,12 @@ XkbFileFromComponents(struct xkb_context *ctx, ParseCommon *defs = NULL, *defsLast = NULL; for (type = FIRST_KEYMAP_FILE_TYPE; type <= LAST_KEYMAP_FILE_TYPE; type++) { - include = IncludeCreate(ctx, components[type], MERGE_DEFAULT); + include = IncludeCreate(bump, ctx, components[type], MERGE_DEFAULT); if (!include) goto err; - file = XkbFileCreate(type, NULL, (ParseCommon *) include, 0); + file = XkbFileCreate(bump, type, NULL, (ParseCommon *) include, 0); if (!file) { - FreeInclude(include); goto err; } @@ -554,168 +546,16 @@ XkbFileFromComponents(struct xkb_context *ctx, defsLast = defsLast->next = &file->common; } - file = XkbFileCreate(FILE_TYPE_KEYMAP, NULL, defs, 0); + file = XkbFileCreate(bump, FILE_TYPE_KEYMAP, NULL, defs, 0); if (!file) goto err; return file; err: - FreeXkbFile((XkbFile *) defs); return NULL; } -static void -FreeExpr(ExprDef *expr) -{ - if (!expr) - return; - - switch (expr->expr.op) { - case EXPR_NEGATE: - case EXPR_UNARY_PLUS: - case EXPR_NOT: - case EXPR_INVERT: - FreeStmt((ParseCommon *) expr->unary.child); - break; - - case EXPR_DIVIDE: - case EXPR_ADD: - case EXPR_SUBTRACT: - case EXPR_MULTIPLY: - case EXPR_ASSIGN: - FreeStmt((ParseCommon *) expr->binary.left); - FreeStmt((ParseCommon *) expr->binary.right); - break; - - case EXPR_ACTION_DECL: - FreeStmt((ParseCommon *) expr->action.args); - break; - - case EXPR_ACTION_LIST: - FreeStmt((ParseCommon *) expr->actions.actions); - break; - - case EXPR_ARRAY_REF: - FreeStmt((ParseCommon *) expr->array_ref.entry); - break; - - case EXPR_KEYSYM_LIST: - free(expr->keysym_list.syms); - break; - - default: - break; - } -} - -static void -FreeInclude(IncludeStmt *incl) -{ - IncludeStmt *next; - - while (incl) - { - next = incl->next_incl; - - free(incl->file); - free(incl->map); - free(incl->modifier); - free(incl->stmt); - - free(incl); - incl = next; - } -} - -void -FreeStmt(ParseCommon *stmt) -{ - ParseCommon *next; - - while (stmt) - { - next = stmt->next; - - switch (stmt->type) { - case STMT_INCLUDE: - FreeInclude((IncludeStmt *) stmt); - /* stmt is already free'd here. */ - stmt = NULL; - break; - case STMT_EXPR: - FreeExpr((ExprDef *) stmt); - break; - case STMT_VAR: - FreeStmt((ParseCommon *) ((VarDef *) stmt)->name); - FreeStmt((ParseCommon *) ((VarDef *) stmt)->value); - break; - case STMT_TYPE: - FreeStmt((ParseCommon *) ((KeyTypeDef *) stmt)->body); - break; - case STMT_INTERP: - FreeStmt((ParseCommon *) ((InterpDef *) stmt)->match); - FreeStmt((ParseCommon *) ((InterpDef *) stmt)->def); - break; - case STMT_VMOD: - FreeStmt((ParseCommon *) ((VModDef *) stmt)->value); - break; - case STMT_SYMBOLS: - FreeStmt((ParseCommon *) ((SymbolsDef *) stmt)->symbols); - break; - case STMT_MODMAP: - FreeStmt((ParseCommon *) ((ModMapDef *) stmt)->keys); - break; - case STMT_GROUP_COMPAT: - FreeStmt((ParseCommon *) ((GroupCompatDef *) stmt)->def); - break; - case STMT_LED_MAP: - FreeStmt((ParseCommon *) ((LedMapDef *) stmt)->body); - break; - case STMT_LED_NAME: - FreeStmt((ParseCommon *) ((LedNameDef *) stmt)->name); - break; - default: - break; - } - - free(stmt); - stmt = next; - } -} - -void -FreeXkbFile(XkbFile *file) -{ - XkbFile *next; - - while (file) - { - next = (XkbFile *) file->common.next; - - switch (file->file_type) { - case FILE_TYPE_KEYMAP: - FreeXkbFile((XkbFile *) file->defs); - break; - - case FILE_TYPE_TYPES: - case FILE_TYPE_COMPAT: - case FILE_TYPE_SYMBOLS: - case FILE_TYPE_KEYCODES: - case FILE_TYPE_GEOMETRY: - FreeStmt(file->defs); - break; - - default: - break; - } - - free(file->name); - free(file); - file = next; - } -} - static const char *xkb_file_type_strings[_FILE_TYPE_NUM_ENTRIES] = { [FILE_TYPE_KEYCODES] = "xkb_keycodes", [FILE_TYPE_TYPES] = "xkb_types", diff --git a/src/xkbcomp/ast-build.h b/src/xkbcomp/ast-build.h index 8f3f8522..e97cebca 100644 --- a/src/xkbcomp/ast-build.h +++ b/src/xkbcomp/ast-build.h @@ -27,98 +27,97 @@ #ifndef XKBCOMP_AST_BUILD_H #define XKBCOMP_AST_BUILD_H +#include "bump.h" #include "ast.h" ExprDef * -ExprCreateString(xkb_atom_t str); +ExprCreateString(struct bump *bump, xkb_atom_t str); ExprDef * -ExprCreateInteger(int ival); +ExprCreateInteger(struct bump *bump, int ival); ExprDef * -ExprCreateFloat(void); +ExprCreateFloat(struct bump *bump); ExprDef * -ExprCreateBoolean(bool set); +ExprCreateBoolean(struct bump *bump, bool set); ExprDef * -ExprCreateKeyName(xkb_atom_t key_name); +ExprCreateKeyName(struct bump *bump, xkb_atom_t key_name); ExprDef * -ExprCreateIdent(xkb_atom_t ident); +ExprCreateIdent(struct bump *bump, xkb_atom_t ident); ExprDef * -ExprCreateUnary(enum expr_op_type op, enum expr_value_type type, +ExprCreateUnary(struct bump *bump, enum expr_op_type op, enum expr_value_type type, ExprDef *child); ExprDef * -ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right); +ExprCreateBinary(struct bump *bump, enum expr_op_type op, ExprDef *left, ExprDef *right); ExprDef * -ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field); +ExprCreateFieldRef(struct bump *bump, xkb_atom_t element, xkb_atom_t field); ExprDef * -ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry); +ExprCreateArrayRef(struct bump *bump, xkb_atom_t element, xkb_atom_t field, ExprDef *entry); ExprDef * -ExprEmptyList(void); +ExprEmptyList(struct bump *bump); ExprDef * -ExprCreateAction(xkb_atom_t name, ExprDef *args); +ExprCreateAction(struct bump *bump, xkb_atom_t name, ExprDef *args); ExprDef * -ExprCreateActionList(ExprDef *actions); +ExprCreateActionList(struct bump *bump, ExprDef *actions); ExprDef * -ExprCreateKeysymList(xkb_keysym_t sym); +ExprCreateKeysymList(struct bump *bump, xkb_keysym_t sym); ExprDef * -ExprAppendKeysymList(ExprDef *list, xkb_keysym_t sym); +ExprAppendKeysymList(struct bump *bump, ExprDef *list, xkb_keysym_t sym); KeycodeDef * -KeycodeCreate(xkb_atom_t name, int64_t value); +KeycodeCreate(struct bump *bump, xkb_atom_t name, int64_t value); KeyAliasDef * -KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real); +KeyAliasCreate(struct bump *bump, xkb_atom_t alias, xkb_atom_t real); VModDef * -VModCreate(xkb_atom_t name, ExprDef *value); +VModCreate(struct bump *bump, xkb_atom_t name, ExprDef *value); VarDef * -VarCreate(ExprDef *name, ExprDef *value); +VarCreate(struct bump *bump, ExprDef *name, ExprDef *value); VarDef * -BoolVarCreate(xkb_atom_t ident, bool set); +BoolVarCreate(struct bump *bump, xkb_atom_t ident, bool set); InterpDef * -InterpCreate(xkb_keysym_t sym, ExprDef *match); +InterpCreate(struct bump *bump, xkb_keysym_t sym, ExprDef *match); KeyTypeDef * -KeyTypeCreate(xkb_atom_t name, VarDef *body); +KeyTypeCreate(struct bump *bump, xkb_atom_t name, VarDef *body); SymbolsDef * -SymbolsCreate(xkb_atom_t keyName, VarDef *symbols); +SymbolsCreate(struct bump *bump, xkb_atom_t keyName, VarDef *symbols); GroupCompatDef * -GroupCompatCreate(unsigned group, ExprDef *def); +GroupCompatCreate(struct bump *bump, unsigned group, ExprDef *def); ModMapDef * -ModMapCreate(xkb_atom_t modifier, ExprDef *keys); +ModMapCreate(struct bump *bump, xkb_atom_t modifier, ExprDef *keys); LedMapDef * -LedMapCreate(xkb_atom_t name, VarDef *body); +LedMapCreate(struct bump *bump, xkb_atom_t name, VarDef *body); LedNameDef * -LedNameCreate(unsigned ndx, ExprDef *name, bool virtual); +LedNameCreate(struct bump *bump, unsigned ndx, ExprDef *name, bool virtual); IncludeStmt * -IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge); +IncludeCreate(struct bump *bump, struct xkb_context *ctx, char *str, + enum merge_mode merge); XkbFile * -XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs, - enum xkb_map_flags flags); - -void -FreeStmt(ParseCommon *stmt); +XkbFileCreate(struct bump *bump, enum xkb_file_type type, char *name, + ParseCommon *defs, enum xkb_map_flags flags); #endif diff --git a/src/xkbcomp/ast.h b/src/xkbcomp/ast.h index e1aff837..5644601d 100644 --- a/src/xkbcomp/ast.h +++ b/src/xkbcomp/ast.h @@ -358,6 +358,7 @@ enum xkb_map_flags { typedef struct { ParseCommon common; + struct bump *bump; enum xkb_file_type file_type; char *name; ParseCommon *defs; diff --git a/src/xkbcomp/compat.c b/src/xkbcomp/compat.c index 8f35b348..20b85c92 100644 --- a/src/xkbcomp/compat.c +++ b/src/xkbcomp/compat.c @@ -55,7 +55,6 @@ #include "action.h" #include "vmod.h" #include "include.h" -#include "util-mem.h" enum si_field { SI_FIELD_VIRTUAL_MOD = (1 << 0), @@ -399,7 +398,7 @@ MergeIncludedCompatMaps(CompatInfo *into, CompatInfo *from, into->mods = from->mods; if (into->name == NULL) { - into->name = steal(&from->name); + into->name = strdup(from->name); } if (darray_empty(into->interps)) { @@ -434,7 +433,7 @@ static void HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge); static bool -HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *include) +HandleIncludeCompatMap(struct bump *bump, CompatInfo *info, IncludeStmt *include) { CompatInfo included; @@ -445,13 +444,13 @@ HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *include) InitCompatInfo(&included, info->ctx, 0 /* unused */, info->actions, &info->mods); - included.name = steal(&include->stmt); + included.name = strdup(include->stmt); for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) { CompatInfo next_incl; XkbFile *file; - file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_COMPAT); + file = ProcessIncludeFile(bump, info->ctx, stmt, FILE_TYPE_COMPAT); if (!file) { info->errorCount += 10; ClearCompatInfo(&included); @@ -470,7 +469,6 @@ HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *include) MergeIncludedCompatMaps(&included, &next_incl, stmt->merge); ClearCompatInfo(&next_incl); - FreeXkbFile(file); } MergeIncludedCompatMaps(info, &included, include->merge); @@ -774,7 +772,7 @@ HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge) for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) { switch (stmt->type) { case STMT_INCLUDE: - ok = HandleIncludeCompatMap(info, (IncludeStmt *) stmt); + ok = HandleIncludeCompatMap(file->bump, info, (IncludeStmt *) stmt); break; case STMT_INTERP: ok = HandleInterpDef(info, (InterpDef *) stmt, merge); diff --git a/src/xkbcomp/include.c b/src/xkbcomp/include.c index 620b2f4f..a1578267 100644 --- a/src/xkbcomp/include.c +++ b/src/xkbcomp/include.c @@ -99,8 +99,8 @@ * */ bool -ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn, - char *nextop_rtrn, char **extra_data) +ParseIncludeMap(struct bump *bump, char **str_inout, char **file_rtrn, + char **map_rtrn, char *nextop_rtrn, char **extra_data) { char *tmp, *str, *next; @@ -130,7 +130,7 @@ ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn, tmp = strchr(str, ':'); if (tmp != NULL) { *tmp++ = '\0'; - *extra_data = strdup(tmp); + *extra_data = bump_strdup(bump, tmp); } else { *extra_data = NULL; @@ -140,27 +140,24 @@ ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn, tmp = strchr(str, '('); if (tmp == NULL) { /* No map. */ - *file_rtrn = strdup(str); + *file_rtrn = bump_strdup(bump, str); *map_rtrn = NULL; } else if (str[0] == '(') { /* Map without file - invalid. */ - free(*extra_data); return false; } else { /* Got a map; separate the file and the map for the strdup's. */ *tmp++ = '\0'; - *file_rtrn = strdup(str); + *file_rtrn = bump_strdup(bump, str); str = tmp; tmp = strchr(str, ')'); if (tmp == NULL || tmp[1] != '\0') { - free(*file_rtrn); - free(*extra_data); return false; } *tmp++ = '\0'; - *map_rtrn = strdup(str); + *map_rtrn = bump_strdup(bump, str); } /* Set up the next file for the next call, if any. */ @@ -294,8 +291,8 @@ ExceedsIncludeMaxDepth(struct xkb_context *ctx, unsigned int include_depth) } XkbFile * -ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt, - enum xkb_file_type file_type) +ProcessIncludeFile(struct bump *bump, struct xkb_context *ctx, + IncludeStmt *stmt, enum xkb_file_type file_type) { FILE *file; XkbFile *xkb_file = NULL; @@ -306,7 +303,7 @@ ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt, return NULL; while (file) { - xkb_file = XkbParseFile(ctx, file, stmt->file, stmt->map); + xkb_file = XkbParseFile(bump, ctx, file, stmt->file, stmt->map); fclose(file); if (xkb_file) { @@ -316,7 +313,6 @@ ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt, "Include file \"%s\" ignored\n", xkb_file_type_to_string(file_type), xkb_file_type_to_string(xkb_file->file_type), stmt->file); - FreeXkbFile(xkb_file); xkb_file = NULL; } else { break; diff --git a/src/xkbcomp/include.h b/src/xkbcomp/include.h index dc71ba18..3cc2c611 100644 --- a/src/xkbcomp/include.h +++ b/src/xkbcomp/include.h @@ -28,6 +28,7 @@ #define XKBCOMP_INCLUDE_H #include "ast.h" +#include "bump.h" /* Reasonable threshold, with plenty of margin for keymaps in the wild */ #define INCLUDE_MAX_DEPTH 15 @@ -39,8 +40,8 @@ ((ch) == MERGE_OVERRIDE_PREFIX || (ch) == MERGE_AUGMENT_PREFIX) bool -ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn, - char *nextop_rtrn, char **extra_data); +ParseIncludeMap(struct bump *bump, char **str_inout, char **file_rtrn, + char **map_rtrn, char *nextop_rtrn, char **extra_data); FILE * FindFileInXkbPath(struct xkb_context *ctx, const char *name, @@ -51,7 +52,7 @@ bool ExceedsIncludeMaxDepth(struct xkb_context *ctx, unsigned int include_depth); XkbFile * -ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt, - enum xkb_file_type file_type); +ProcessIncludeFile(struct bump *bump, struct xkb_context *ctx, + IncludeStmt *stmt, enum xkb_file_type file_type); #endif diff --git a/src/xkbcomp/keycodes.c b/src/xkbcomp/keycodes.c index 242b5fe9..0840fdf2 100644 --- a/src/xkbcomp/keycodes.c +++ b/src/xkbcomp/keycodes.c @@ -30,7 +30,6 @@ #include "text.h" #include "expr.h" #include "include.h" -#include "util-mem.h" typedef struct { enum merge_mode merge; @@ -267,7 +266,7 @@ MergeIncludedKeycodes(KeyNamesInfo *into, KeyNamesInfo *from, } if (into->name == NULL) { - into->name = steal(&from->name); + into->name = strdup(from->name); } /* Merge key names. */ @@ -336,7 +335,7 @@ static void HandleKeycodesFile(KeyNamesInfo *info, XkbFile *file, enum merge_mode merge); static bool -HandleIncludeKeycodes(KeyNamesInfo *info, IncludeStmt *include) +HandleIncludeKeycodes(struct bump *bump, KeyNamesInfo *info, IncludeStmt *include) { KeyNamesInfo included; @@ -346,13 +345,13 @@ HandleIncludeKeycodes(KeyNamesInfo *info, IncludeStmt *include) } InitKeyNamesInfo(&included, info->ctx, 0 /* unused */); - included.name = steal(&include->stmt); + included.name = strdup(include->stmt); for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) { KeyNamesInfo next_incl; XkbFile *file; - file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_KEYCODES); + file = ProcessIncludeFile(bump, info->ctx, stmt, FILE_TYPE_KEYCODES); if (!file) { info->errorCount += 10; ClearKeyNamesInfo(&included); @@ -366,7 +365,6 @@ HandleIncludeKeycodes(KeyNamesInfo *info, IncludeStmt *include) MergeIncludedKeycodes(&included, &next_incl, stmt->merge); ClearKeyNamesInfo(&next_incl); - FreeXkbFile(file); } MergeIncludedKeycodes(info, &included, include->merge); @@ -503,7 +501,7 @@ HandleKeycodesFile(KeyNamesInfo *info, XkbFile *file, enum merge_mode merge) for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) { switch (stmt->type) { case STMT_INCLUDE: - ok = HandleIncludeKeycodes(info, (IncludeStmt *) stmt); + ok = HandleIncludeKeycodes(file->bump, info, (IncludeStmt *) stmt); break; case STMT_KEYCODE: ok = HandleKeycodeDef(info, (KeycodeDef *) stmt, merge); diff --git a/src/xkbcomp/parser-priv.h b/src/xkbcomp/parser-priv.h index f10351a9..bc7f18dc 100644 --- a/src/xkbcomp/parser-priv.h +++ b/src/xkbcomp/parser-priv.h @@ -36,7 +36,7 @@ int _xkbcommon_lex(YYSTYPE *yylval, struct scanner *scanner); XkbFile * -parse(struct xkb_context *ctx, struct scanner *scanner, const char *map); +parse(struct bump *bump, struct xkb_context *ctx, struct scanner *scanner, const char *map); int keyword_to_token(const char *string, size_t len); diff --git a/src/xkbcomp/parser.y b/src/xkbcomp/parser.y index ff4bbe80..d888c275 100644 --- a/src/xkbcomp/parser.y +++ b/src/xkbcomp/parser.y @@ -40,6 +40,7 @@ #include "keysym.h" struct parser_param { + struct bump *bump; struct xkb_context *ctx; struct scanner *scanner; XkbFile *rtrn; @@ -168,6 +169,7 @@ resolve_keysym(struct parser_param *param, const char *name, xkb_keysym_t *sym_r int64_t num; enum xkb_file_type file_type; char *str; + char *bumpStr; xkb_atom_t atom; enum merge_mode merge; enum xkb_map_flags mapFlags; @@ -201,7 +203,7 @@ resolve_keysym(struct parser_param *param, const char *name, xkb_keysym_t *sym_r %type MergeMode OptMergeMode %type XkbCompositeType FileType %type Flag Flags OptFlags -%type MapName OptMapName +%type MapName OptMapName %type FieldSpec Ident Element String %type KeySym %type Decl @@ -229,15 +231,6 @@ resolve_keysym(struct parser_param *param, const char *name, xkb_keysym_t *sym_r %type XkbMapConfigList %type XkbCompositeMap -%destructor { FreeStmt((ParseCommon *) $$); } - - -%destructor { FreeStmt((ParseCommon *) $$.head); } - -/* The destructor also runs on the start symbol when the parser *succeeds*. - * The `if` here catches this case. */ -%destructor { if (!param->rtrn) FreeXkbFile($$); } -%destructor { FreeXkbFile($$.head); } %destructor { free($$); } %% @@ -265,7 +258,7 @@ XkbFile : XkbCompositeMap XkbCompositeMap : OptFlags XkbCompositeType OptMapName OBRACE XkbMapConfigList CBRACE SEMI - { $$ = XkbFileCreate($2, $3, (ParseCommon *) $5.head, $1); } + { $$ = XkbFileCreate(param->bump, $2, $3, (ParseCommon *) $5.head, $1); } ; XkbCompositeType: XKB_KEYMAP { $$ = FILE_TYPE_KEYMAP; } @@ -283,7 +276,7 @@ XkbMapConfig : OptFlags FileType OptMapName OBRACE DeclList CBRACE SEMI { - $$ = XkbFileCreate($2, $3, $5.head, $1); + $$ = XkbFileCreate(param->bump, $2, $3, $5.head, $1); } ; @@ -396,25 +389,25 @@ Decl : OptMergeMode VarDecl | OptMergeMode DoodadDecl { $$ = NULL; } | MergeMode STRING { - $$ = (ParseCommon *) IncludeCreate(param->ctx, $2, $1); + $$ = (ParseCommon *) IncludeCreate(param->bump, param->ctx, $2, $1); free($2); } ; VarDecl : Lhs EQUALS Expr SEMI - { $$ = VarCreate($1, $3); } + { $$ = VarCreate(param->bump, $1, $3); } | Ident SEMI - { $$ = BoolVarCreate($1, true); } + { $$ = BoolVarCreate(param->bump, $1, true); } | EXCLAM Ident SEMI - { $$ = BoolVarCreate($2, false); } + { $$ = BoolVarCreate(param->bump, $2, false); } ; KeyNameDecl : KEYNAME EQUALS KeyCode SEMI - { $$ = KeycodeCreate($1, $3); } + { $$ = KeycodeCreate(param->bump, $1, $3); } ; KeyAliasDecl : ALIAS KEYNAME EQUALS KEYNAME SEMI - { $$ = KeyAliasCreate($2, $4); } + { $$ = KeyAliasCreate(param->bump, $2, $4); } ; VModDecl : VIRTUAL_MODS VModDefList SEMI @@ -428,9 +421,9 @@ VModDefList : VModDefList COMMA VModDef ; VModDef : Ident - { $$ = VModCreate($1, NULL); } + { $$ = VModCreate(param->bump, $1, NULL); } | Ident EQUALS Expr - { $$ = VModCreate($1, $3); } + { $$ = VModCreate(param->bump, $1, $3); } ; InterpretDecl : INTERPRET InterpretMatch OBRACE @@ -440,9 +433,9 @@ InterpretDecl : INTERPRET InterpretMatch OBRACE ; InterpretMatch : KeySym PLUS Expr - { $$ = InterpCreate($1, $3); } + { $$ = InterpCreate(param->bump, $1, $3); } | KeySym - { $$ = InterpCreate($1, NULL); } + { $$ = InterpCreate(param->bump, $1, NULL); } ; VarDeclList : VarDeclList VarDecl @@ -454,13 +447,13 @@ VarDeclList : VarDeclList VarDecl KeyTypeDecl : TYPE String OBRACE VarDeclList CBRACE SEMI - { $$ = KeyTypeCreate($2, $4.head); } + { $$ = KeyTypeCreate(param->bump, $2, $4.head); } ; SymbolsDecl : KEY KEYNAME OBRACE OptSymbolsBody CBRACE SEMI - { $$ = SymbolsCreate($2, $4.head); } + { $$ = SymbolsCreate(param->bump, $2, $4.head); } ; OptSymbolsBody : SymbolsBody { $$ = $1; } @@ -473,11 +466,11 @@ SymbolsBody : SymbolsBody COMMA SymbolsVarDecl { $$.head = $$.last = $1; } ; -SymbolsVarDecl : Lhs EQUALS Expr { $$ = VarCreate($1, $3); } - | Lhs EQUALS ArrayInit { $$ = VarCreate($1, $3); } - | Ident { $$ = BoolVarCreate($1, true); } - | EXCLAM Ident { $$ = BoolVarCreate($2, false); } - | ArrayInit { $$ = VarCreate(NULL, $1); } +SymbolsVarDecl : Lhs EQUALS Expr { $$ = VarCreate(param->bump, $1, $3); } + | Lhs EQUALS ArrayInit { $$ = VarCreate(param->bump, $1, $3); } + | Ident { $$ = BoolVarCreate(param->bump, $1, true); } + | EXCLAM Ident { $$ = BoolVarCreate(param->bump, $2, false); } + | ArrayInit { $$ = VarCreate(param->bump, NULL, $1); } ; ArrayInit : OBRACKET MultiKeySymList CBRACKET @@ -485,25 +478,25 @@ ArrayInit : OBRACKET MultiKeySymList CBRACKET | OBRACKET MultiActionList CBRACKET { $$ = $2.head; } | OBRACKET CBRACKET - { $$ = ExprEmptyList(); } + { $$ = ExprEmptyList(param->bump); } ; GroupCompatDecl : GROUP Integer EQUALS Expr SEMI - { $$ = GroupCompatCreate($2, $4); } + { $$ = GroupCompatCreate(param->bump, $2, $4); } ; ModMapDecl : MODIFIER_MAP Ident OBRACE ExprList CBRACE SEMI - { $$ = ModMapCreate($2, $4.head); } + { $$ = ModMapCreate(param->bump, $2, $4.head); } ; LedMapDecl: INDICATOR String OBRACE VarDeclList CBRACE SEMI - { $$ = LedMapCreate($2, $4.head); } + { $$ = LedMapCreate(param->bump, $2, $4.head); } ; LedNameDecl: INDICATOR Integer EQUALS Expr SEMI - { $$ = LedNameCreate($2, $4, false); } + { $$ = LedNameCreate(param->bump, $2, $4, false); } | VIRTUAL INDICATOR Integer EQUALS Expr SEMI - { $$ = LedNameCreate($3, $5, true); } + { $$ = LedNameCreate(param->bump, $3, $5, true); } ; ShapeDecl : SHAPE String OBRACE OutlineList CBRACE SEMI @@ -523,11 +516,11 @@ SectionBody : SectionBody SectionBodyItem { $$ = NULL;} SectionBodyItem : ROW OBRACE RowBody CBRACE SEMI { $$ = NULL; } | VarDecl - { FreeStmt((ParseCommon *) $1); $$ = NULL; } + { $$ = NULL; } | DoodadDecl { $$ = NULL; } | LedMapDecl - { FreeStmt((ParseCommon *) $1); $$ = NULL; } + { $$ = NULL; } | OverlayDecl { $$ = NULL; } ; @@ -538,7 +531,7 @@ RowBody : RowBody RowBodyItem { $$ = NULL;} RowBodyItem : KEYS OBRACE Keys CBRACE SEMI { $$ = NULL; } | VarDecl - { FreeStmt((ParseCommon *) $1); $$ = NULL; } + { $$ = NULL; } ; Keys : Keys COMMA Key { $$ = NULL; } @@ -548,7 +541,7 @@ Keys : Keys COMMA Key { $$ = NULL; } Key : KEYNAME { $$ = NULL; } | OBRACE ExprList CBRACE - { FreeStmt((ParseCommon *) $2.head); $$ = NULL; } + { $$ = NULL; } ; OverlayDecl : OVERLAY String OBRACE OverlayKeyList CBRACE SEMI @@ -573,7 +566,7 @@ OutlineInList : OBRACE CoordList CBRACE | Ident EQUALS OBRACE CoordList CBRACE { (void) $4; $$ = NULL; } | Ident EQUALS Expr - { FreeStmt((ParseCommon *) $3); $$ = NULL; } + { $$ = NULL; } ; CoordList : CoordList COMMA Coord @@ -587,7 +580,7 @@ Coord : OBRACKET SignedNumber COMMA SignedNumber CBRACKET ; DoodadDecl : DoodadType String OBRACE VarDeclList CBRACE SEMI - { FreeStmt((ParseCommon *) $4.head); $$ = NULL; } + { $$ = NULL; } ; DoodadType : TEXT { $$ = 0; } @@ -653,31 +646,31 @@ ExprList : ExprList COMMA Expr ; Expr : Expr DIVIDE Expr - { $$ = ExprCreateBinary(EXPR_DIVIDE, $1, $3); } + { $$ = ExprCreateBinary(param->bump, EXPR_DIVIDE, $1, $3); } | Expr PLUS Expr - { $$ = ExprCreateBinary(EXPR_ADD, $1, $3); } + { $$ = ExprCreateBinary(param->bump, EXPR_ADD, $1, $3); } | Expr MINUS Expr - { $$ = ExprCreateBinary(EXPR_SUBTRACT, $1, $3); } + { $$ = ExprCreateBinary(param->bump, EXPR_SUBTRACT, $1, $3); } | Expr TIMES Expr - { $$ = ExprCreateBinary(EXPR_MULTIPLY, $1, $3); } + { $$ = ExprCreateBinary(param->bump, EXPR_MULTIPLY, $1, $3); } | Lhs EQUALS Expr - { $$ = ExprCreateBinary(EXPR_ASSIGN, $1, $3); } + { $$ = ExprCreateBinary(param->bump, EXPR_ASSIGN, $1, $3); } | Term { $$ = $1; } ; Term : MINUS Term - { $$ = ExprCreateUnary(EXPR_NEGATE, $2->expr.value_type, $2); } + { $$ = ExprCreateUnary(param->bump, EXPR_NEGATE, $2->expr.value_type, $2); } | PLUS Term - { $$ = ExprCreateUnary(EXPR_UNARY_PLUS, $2->expr.value_type, $2); } + { $$ = ExprCreateUnary(param->bump, EXPR_UNARY_PLUS, $2->expr.value_type, $2); } | EXCLAM Term - { $$ = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, $2); } + { $$ = ExprCreateUnary(param->bump, EXPR_NOT, EXPR_TYPE_BOOLEAN, $2); } | INVERT Term - { $$ = ExprCreateUnary(EXPR_INVERT, $2->expr.value_type, $2); } + { $$ = ExprCreateUnary(param->bump, EXPR_INVERT, $2->expr.value_type, $2); } | Lhs { $$ = $1; } | FieldSpec OPAREN OptExprList CPAREN %prec OPAREN - { $$ = ExprCreateAction($1, $3.head); } + { $$ = ExprCreateAction(param->bump, $1, $3.head); } | Terminal { $$ = $1; } | OPAREN Expr CPAREN @@ -686,14 +679,14 @@ Term : MINUS Term MultiActionList : MultiActionList COMMA Action { - ExprDef *expr = ExprCreateActionList($3); + ExprDef *expr = ExprCreateActionList(param->bump, $3); $$ = $1; $$.last->common.next = &expr->common; $$.last = expr; } | MultiActionList COMMA Actions { $$ = $1; $$.last->common.next = &$3->common; $$.last = $3; } | Action - { $$.head = $$.last = ExprCreateActionList($1); } + { $$.head = $$.last = ExprCreateActionList(param->bump, $1); } | Actions { $$.head = $$.last = $1; } ; @@ -705,53 +698,53 @@ ActionList : ActionList COMMA Action ; Actions : OBRACE ActionList CBRACE - { $$ = ExprCreateActionList($2.head); } + { $$ = ExprCreateActionList(param->bump, $2.head); } ; Action : FieldSpec OPAREN OptExprList CPAREN - { $$ = ExprCreateAction($1, $3.head); } + { $$ = ExprCreateAction(param->bump, $1, $3.head); } ; Lhs : FieldSpec - { $$ = ExprCreateIdent($1); } + { $$ = ExprCreateIdent(param->bump, $1); } | FieldSpec DOT FieldSpec - { $$ = ExprCreateFieldRef($1, $3); } + { $$ = ExprCreateFieldRef(param->bump, $1, $3); } | FieldSpec OBRACKET Expr CBRACKET - { $$ = ExprCreateArrayRef(XKB_ATOM_NONE, $1, $3); } + { $$ = ExprCreateArrayRef(param->bump, XKB_ATOM_NONE, $1, $3); } | FieldSpec DOT FieldSpec OBRACKET Expr CBRACKET - { $$ = ExprCreateArrayRef($1, $3, $5); } + { $$ = ExprCreateArrayRef(param->bump, $1, $3, $5); } ; Terminal : String - { $$ = ExprCreateString($1); } + { $$ = ExprCreateString(param->bump, $1); } | Integer - { $$ = ExprCreateInteger($1); } + { $$ = ExprCreateInteger(param->bump, $1); } | Float - { $$ = ExprCreateFloat(/* Discard $1 */); } + { $$ = ExprCreateFloat(param->bump /* Discard $1 */); } | KEYNAME - { $$ = ExprCreateKeyName($1); } + { $$ = ExprCreateKeyName(param->bump, $1); } ; MultiKeySymList : MultiKeySymList COMMA KeySym { - ExprDef *expr = ExprCreateKeysymList($3); + ExprDef *expr = ExprCreateKeysymList(param->bump, $3); $$ = $1; $$.last->common.next = &expr->common; $$.last = expr; } | MultiKeySymList COMMA KeySyms { $$ = $1; $$.last->common.next = &$3->common; $$.last = $3; } | KeySym - { $$.head = $$.last = ExprCreateKeysymList($1); } + { $$.head = $$.last = ExprCreateKeysymList(param->bump, $1); } | KeySyms { $$.head = $$.last = $1; } ; KeySymList : KeySymList COMMA KeySym - { $$ = ExprAppendKeysymList($1, $3); } + { $$ = ExprAppendKeysymList(param->bump, $1, $3); } | KeySym COMMA KeySym { - $$ = ExprCreateKeysymList($1); - $$ = ExprAppendKeysymList($$, $3); + $$ = ExprCreateKeysymList(param->bump, $1); + $$ = ExprAppendKeysymList(param->bump, $$, $3); } ; @@ -840,17 +833,18 @@ OptMapName : MapName { $$ = $1; } | { $$ = NULL; } ; -MapName : STRING { $$ = $1; } +MapName : STRING { $$ = bump_strdup(param->bump, $1); free($1); } ; %% XkbFile * -parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) +parse(struct bump *bump, struct xkb_context *ctx, struct scanner *scanner, const char *map) { int ret; XkbFile *first = NULL; struct parser_param param = { + .bump = bump, .scanner = scanner, .ctx = ctx, .rtrn = NULL, @@ -869,28 +863,20 @@ parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) if (map) { if (streq_not_null(map, param.rtrn->name)) return param.rtrn; - else - FreeXkbFile(param.rtrn); } else { if (param.rtrn->flags & MAP_IS_DEFAULT) { - FreeXkbFile(first); return param.rtrn; } else if (!first) { first = param.rtrn; } - else { - FreeXkbFile(param.rtrn); - } } param.rtrn = NULL; } if (ret != 0) { - /* Some error happend; clear the Xkbfiles parsed so far */ - FreeXkbFile(first); - FreeXkbFile(param.rtrn); + /* Some error happend. */ return NULL; } diff --git a/src/xkbcomp/scanner.c b/src/xkbcomp/scanner.c index a320b8d6..de6cbf57 100644 --- a/src/xkbcomp/scanner.c +++ b/src/xkbcomp/scanner.c @@ -198,7 +198,8 @@ _xkbcommon_lex(YYSTYPE *yylval, struct scanner *s) } XkbFile * -XkbParseString(struct xkb_context *ctx, const char *string, size_t len, +XkbParseString(struct bump *bump, struct xkb_context *ctx, + const char *string, size_t len, const char *file_name, const char *map) { struct scanner scanner; @@ -217,11 +218,11 @@ XkbParseString(struct xkb_context *ctx, const char *string, size_t len, return NULL; } - return parse(ctx, &scanner, map); + return parse(bump, ctx, &scanner, map); } XkbFile * -XkbParseFile(struct xkb_context *ctx, FILE *file, +XkbParseFile(struct bump *bump, struct xkb_context *ctx, FILE *file, const char *file_name, const char *map) { bool ok; @@ -237,7 +238,7 @@ XkbParseFile(struct xkb_context *ctx, FILE *file, return NULL; } - xkb_file = XkbParseString(ctx, string, size, file_name, map); + xkb_file = XkbParseString(bump, ctx, string, size, file_name, map); unmap_file(string, size); return xkb_file; } diff --git a/src/xkbcomp/symbols.c b/src/xkbcomp/symbols.c index aad7f3c8..6d91ffa5 100644 --- a/src/xkbcomp/symbols.c +++ b/src/xkbcomp/symbols.c @@ -651,7 +651,7 @@ MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from, into->mods = from->mods; if (into->name == NULL) { - into->name = steal(&from->name); + into->name = strdup(from->name); } group_names_in_both = MIN(darray_size(into->group_names), @@ -700,7 +700,7 @@ static void HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge); static bool -HandleIncludeSymbols(SymbolsInfo *info, IncludeStmt *include) +HandleIncludeSymbols(struct bump *bump, SymbolsInfo *info, IncludeStmt *include) { SymbolsInfo included; @@ -711,13 +711,13 @@ HandleIncludeSymbols(SymbolsInfo *info, IncludeStmt *include) InitSymbolsInfo(&included, info->keymap, 0 /* unused */, info->actions, &info->mods); - included.name = steal(&include->stmt); + included.name = strdup(include->stmt); for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) { SymbolsInfo next_incl; XkbFile *file; - file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_SYMBOLS); + file = ProcessIncludeFile(bump, info->ctx, stmt, FILE_TYPE_SYMBOLS); if (!file) { info->errorCount += 10; ClearSymbolsInfo(&included); @@ -755,7 +755,6 @@ HandleIncludeSymbols(SymbolsInfo *info, IncludeStmt *include) MergeIncludedSymbols(&included, &next_incl, stmt->merge); ClearSymbolsInfo(&next_incl); - FreeXkbFile(file); } MergeIncludedSymbols(info, &included, include->merge); @@ -1443,7 +1442,7 @@ HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge) for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) { switch (stmt->type) { case STMT_INCLUDE: - ok = HandleIncludeSymbols(info, (IncludeStmt *) stmt); + ok = HandleIncludeSymbols(file->bump, info, (IncludeStmt *) stmt); break; case STMT_SYMBOLS: ok = HandleSymbolsDef(info, (SymbolsDef *) stmt); diff --git a/src/xkbcomp/types.c b/src/xkbcomp/types.c index 85c33ed7..ae10abc7 100644 --- a/src/xkbcomp/types.c +++ b/src/xkbcomp/types.c @@ -31,7 +31,6 @@ #include "vmod.h" #include "expr.h" #include "include.h" -#include "util-mem.h" enum type_field { TYPE_FIELD_MASK = (1 << 0), @@ -193,7 +192,7 @@ MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from, into->mods = from->mods; if (into->name == NULL) { - into->name = steal(&from->name); + into->name = strdup(from->name); } if (darray_empty(into->types)) { @@ -218,7 +217,7 @@ static void HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge); static bool -HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *include) +HandleIncludeKeyTypes(struct bump *bump, KeyTypesInfo *info, IncludeStmt *include) { KeyTypesInfo included; @@ -228,13 +227,13 @@ HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *include) } InitKeyTypesInfo(&included, info->ctx, 0 /* unused */, &info->mods); - included.name = steal(&include->stmt); + included.name = strdup(include->stmt); for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) { KeyTypesInfo next_incl; XkbFile *file; - file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_TYPES); + file = ProcessIncludeFile(bump, info->ctx, stmt, FILE_TYPE_TYPES); if (!file) { info->errorCount += 10; ClearKeyTypesInfo(&included); @@ -249,7 +248,6 @@ HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *include) MergeIncludedKeyTypes(&included, &next_incl, stmt->merge); ClearKeyTypesInfo(&next_incl); - FreeXkbFile(file); } MergeIncludedKeyTypes(info, &included, include->merge); @@ -665,7 +663,7 @@ HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge) for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) { switch (stmt->type) { case STMT_INCLUDE: - ok = HandleIncludeKeyTypes(info, (IncludeStmt *) stmt); + ok = HandleIncludeKeyTypes(file->bump, info, (IncludeStmt *) stmt); break; case STMT_TYPE: ok = HandleKeyTypeDef(info, (KeyTypeDef *) stmt, merge); diff --git a/src/xkbcomp/xkbcomp-priv.h b/src/xkbcomp/xkbcomp-priv.h index 9156922c..32f07ba8 100644 --- a/src/xkbcomp/xkbcomp-priv.h +++ b/src/xkbcomp/xkbcomp-priv.h @@ -29,6 +29,7 @@ #include "keymap.h" #include "ast.h" +#include "bump.h" struct xkb_component_names { char *keycodes; @@ -41,19 +42,16 @@ char * text_v1_keymap_get_as_string(struct xkb_keymap *keymap); XkbFile * -XkbParseFile(struct xkb_context *ctx, FILE *file, +XkbParseFile(struct bump *bump, struct xkb_context *ctx, FILE *file, const char *file_name, const char *map); XkbFile * -XkbParseString(struct xkb_context *ctx, +XkbParseString(struct bump *bump, struct xkb_context *ctx, const char *string, size_t len, const char *file_name, const char *map); -void -FreeXkbFile(XkbFile *file); - XkbFile * -XkbFileFromComponents(struct xkb_context *ctx, +XkbFileFromComponents(struct bump *bump, struct xkb_context *ctx, const struct xkb_component_names *kkctgs); bool diff --git a/src/xkbcomp/xkbcomp.c b/src/xkbcomp/xkbcomp.c index 05a83a1c..bee76b7d 100644 --- a/src/xkbcomp/xkbcomp.c +++ b/src/xkbcomp/xkbcomp.c @@ -29,6 +29,7 @@ #include "config.h" +#include "bump.h" #include "xkbcomp-priv.h" #include "rules.h" @@ -78,12 +79,15 @@ text_v1_keymap_new_from_names(struct xkb_keymap *keymap, return false; } + struct bump bump; + bump_init(&bump); + log_dbg(keymap->ctx, XKB_LOG_MESSAGE_NO_ID, "Compiling from KcCGST: keycodes '%s', types '%s', " "compat '%s', symbols '%s'\n", kccgst.keycodes, kccgst.types, kccgst.compat, kccgst.symbols); - file = XkbFileFromComponents(keymap->ctx, &kccgst); + file = XkbFileFromComponents(&bump, keymap->ctx, &kccgst); free(kccgst.keycodes); free(kccgst.types); @@ -93,11 +97,13 @@ text_v1_keymap_new_from_names(struct xkb_keymap *keymap, if (!file) { log_err(keymap->ctx, XKB_ERROR_KEYMAP_COMPILATION_FAILED, "Failed to generate parsed XKB file from components\n"); - return false; + ok = false; + goto out; } ok = compile_keymap_file(keymap, file); - FreeXkbFile(file); +out: + bump_uninit(&bump); return ok; } @@ -108,15 +114,20 @@ text_v1_keymap_new_from_string(struct xkb_keymap *keymap, bool ok; XkbFile *xkb_file; - xkb_file = XkbParseString(keymap->ctx, string, len, "(input string)", NULL); + struct bump bump; + bump_init(&bump); + + xkb_file = XkbParseString(&bump, keymap->ctx, string, len, "(input string)", NULL); if (!xkb_file) { log_err(keymap->ctx, XKB_ERROR_KEYMAP_COMPILATION_FAILED, "Failed to parse input xkb string\n"); - return false; + ok = false; + goto out; } ok = compile_keymap_file(keymap, xkb_file); - FreeXkbFile(xkb_file); +out: + bump_uninit(&bump); return ok; } @@ -126,15 +137,20 @@ text_v1_keymap_new_from_file(struct xkb_keymap *keymap, FILE *file) bool ok; XkbFile *xkb_file; - xkb_file = XkbParseFile(keymap->ctx, file, "(unknown file)", NULL); + struct bump bump; + bump_init(&bump); + + xkb_file = XkbParseFile(&bump, keymap->ctx, file, "(unknown file)", NULL); if (!xkb_file) { log_err(keymap->ctx, XKB_ERROR_KEYMAP_COMPILATION_FAILED, "Failed to parse input xkb file\n"); - return false; + ok = false; + goto out; } ok = compile_keymap_file(keymap, xkb_file); - FreeXkbFile(xkb_file); +out: + bump_uninit(&bump); return ok; }