1 /************************************************************
2 * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
4 * Permission to use, copy, modify, and distribute this
5 * software and its documentation for any purpose and without
6 * fee is hereby granted, provided that the above copyright
7 * notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting
9 * documentation, and that the name of Silicon Graphics not be
10 * used in advertising or publicity pertaining to distribution
11 * of the software without specific prior written permission.
12 * Silicon Graphics makes no representation about the suitability
13 * of this software for any purpose. It is provided "as is"
14 * without any express or implied warranty.
16 * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 * THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
28 * Copyright © 2012 Intel Corporation
29 * Copyright © 2012 Ran Benita <ran234@gmail.com>
31 * Permission is hereby granted, free of charge, to any person obtaining a
32 * copy of this software and associated documentation files (the "Software"),
33 * to deal in the Software without restriction, including without limitation
34 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
35 * and/or sell copies of the Software, and to permit persons to whom the
36 * Software is furnished to do so, subject to the following conditions:
38 * The above copyright notice and this permission notice (including the next
39 * paragraph) shall be included in all copies or substantial portions of the
42 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
45 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
47 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
48 * DEALINGS IN THE SOFTWARE.
50 * Author: Daniel Stone <daniel@fooishbar.org>
51 * Ran Benita <ran234@gmail.com>
56 #include "xkbcomp-priv.h"
57 #include "ast-build.h"
61 ExprCreate(enum expr_op_type op, enum expr_value_type type, size_t size)
63 ExprDef *expr = malloc(size);
67 expr->common.type = STMT_EXPR;
68 expr->common.next = NULL;
70 expr->expr.value_type = type;
76 ExprCreateString(xkb_atom_t str)
78 ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING, sizeof(ExprString));
81 expr->string.str = str;
86 ExprCreateInteger(int ival)
88 ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT, sizeof(ExprInteger));
91 expr->integer.ival = ival;
98 ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_FLOAT, sizeof(ExprFloat));
105 ExprCreateBoolean(bool set)
107 ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN, sizeof(ExprBoolean));
110 expr->boolean.set = set;
115 ExprCreateKeyName(xkb_atom_t key_name)
117 ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME, sizeof(ExprKeyName));
120 expr->key_name.key_name = key_name;
125 ExprCreateIdent(xkb_atom_t ident)
127 ExprDef *expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN, sizeof(ExprIdent));
130 expr->ident.ident = ident;
135 ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
138 ExprDef *expr = ExprCreate(op, type, sizeof(ExprUnary));
141 expr->unary.child = child;
146 ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
148 ExprDef *expr = ExprCreate(op, EXPR_TYPE_UNKNOWN, sizeof(ExprBinary));
152 if (op == EXPR_ASSIGN || left->expr.value_type == EXPR_TYPE_UNKNOWN)
153 expr->expr.value_type = right->expr.value_type;
154 else if (left->expr.value_type == right->expr.value_type ||
155 right->expr.value_type == EXPR_TYPE_UNKNOWN)
156 expr->expr.value_type = left->expr.value_type;
157 expr->binary.left = left;
158 expr->binary.right = right;
164 ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field)
166 ExprDef *expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN, sizeof(ExprFieldRef));
169 expr->field_ref.element = element;
170 expr->field_ref.field = field;
175 ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry)
177 ExprDef *expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN, sizeof(ExprArrayRef));
180 expr->array_ref.element = element;
181 expr->array_ref.field = field;
182 expr->array_ref.entry = entry;
187 ExprCreateAction(xkb_atom_t name, ExprDef *args)
189 ExprDef *expr = ExprCreate(EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN, sizeof(ExprAction));
192 expr->action.name = name;
193 expr->action.args = args;
198 ExprCreateActionList(ExprDef *actions)
200 ExprDef *expr = ExprCreate(EXPR_ACTION_LIST, EXPR_TYPE_ACTIONS, sizeof(ExprActionList));
203 expr->actions.actions = actions;
208 ExprCreateKeysymList(xkb_keysym_t sym)
210 ExprDef *expr = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS, sizeof(ExprKeysymList));
214 darray_init(expr->keysym_list.syms);
215 darray_init(expr->keysym_list.symsMapIndex);
216 darray_init(expr->keysym_list.symsNumEntries);
218 darray_append(expr->keysym_list.syms, sym);
219 darray_append(expr->keysym_list.symsMapIndex, 0);
220 darray_append(expr->keysym_list.symsNumEntries, 1);
226 ExprCreateMultiKeysymList(ExprDef *expr)
228 unsigned nLevels = darray_size(expr->keysym_list.symsMapIndex);
230 darray_resize(expr->keysym_list.symsMapIndex, 1);
231 darray_resize(expr->keysym_list.symsNumEntries, 1);
232 darray_item(expr->keysym_list.symsMapIndex, 0) = 0;
233 darray_item(expr->keysym_list.symsNumEntries, 0) = nLevels;
239 ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym)
241 unsigned nSyms = darray_size(expr->keysym_list.syms);
243 darray_append(expr->keysym_list.symsMapIndex, nSyms);
244 darray_append(expr->keysym_list.symsNumEntries, 1);
245 darray_append(expr->keysym_list.syms, sym);
251 ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append)
253 unsigned nSyms = darray_size(expr->keysym_list.syms);
254 unsigned numEntries = darray_size(append->keysym_list.syms);
256 darray_append(expr->keysym_list.symsMapIndex, nSyms);
257 darray_append(expr->keysym_list.symsNumEntries, numEntries);
258 darray_concat(expr->keysym_list.syms, append->keysym_list.syms);
260 FreeStmt((ParseCommon *) append);
266 KeycodeCreate(xkb_atom_t name, int64_t value)
268 KeycodeDef *def = malloc(sizeof(*def));
272 def->common.type = STMT_KEYCODE;
273 def->common.next = NULL;
281 KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real)
283 KeyAliasDef *def = malloc(sizeof(*def));
287 def->common.type = STMT_ALIAS;
288 def->common.next = NULL;
296 VModCreate(xkb_atom_t name, ExprDef *value)
298 VModDef *def = malloc(sizeof(*def));
302 def->common.type = STMT_VMOD;
303 def->common.next = NULL;
311 VarCreate(ExprDef *name, ExprDef *value)
313 VarDef *def = malloc(sizeof(*def));
317 def->common.type = STMT_VAR;
318 def->common.next = NULL;
326 BoolVarCreate(xkb_atom_t ident, bool set)
328 ExprDef *name, *value;
330 if (!(name = ExprCreateIdent(ident))) {
333 if (!(value = ExprCreateBoolean(set))) {
334 FreeStmt((ParseCommon *) name);
337 if (!(def = VarCreate(name, value))) {
338 FreeStmt((ParseCommon *) name);
339 FreeStmt((ParseCommon *) value);
346 InterpCreate(xkb_keysym_t sym, ExprDef *match)
348 InterpDef *def = malloc(sizeof(*def));
352 def->common.type = STMT_INTERP;
353 def->common.next = NULL;
362 KeyTypeCreate(xkb_atom_t name, VarDef *body)
364 KeyTypeDef *def = malloc(sizeof(*def));
368 def->common.type = STMT_TYPE;
369 def->common.next = NULL;
370 def->merge = MERGE_DEFAULT;
378 SymbolsCreate(xkb_atom_t keyName, VarDef *symbols)
380 SymbolsDef *def = malloc(sizeof(*def));
384 def->common.type = STMT_SYMBOLS;
385 def->common.next = NULL;
386 def->merge = MERGE_DEFAULT;
387 def->keyName = keyName;
388 def->symbols = symbols;
394 GroupCompatCreate(unsigned group, ExprDef *val)
396 GroupCompatDef *def = malloc(sizeof(*def));
400 def->common.type = STMT_GROUP_COMPAT;
401 def->common.next = NULL;
402 def->merge = MERGE_DEFAULT;
410 ModMapCreate(xkb_atom_t modifier, ExprDef *keys)
412 ModMapDef *def = malloc(sizeof(*def));
416 def->common.type = STMT_MODMAP;
417 def->common.next = NULL;
418 def->merge = MERGE_DEFAULT;
419 def->modifier = modifier;
426 LedMapCreate(xkb_atom_t name, VarDef *body)
428 LedMapDef *def = malloc(sizeof(*def));
432 def->common.type = STMT_LED_MAP;
433 def->common.next = NULL;
434 def->merge = MERGE_DEFAULT;
442 LedNameCreate(unsigned ndx, ExprDef *name, bool virtual)
444 LedNameDef *def = malloc(sizeof(*def));
448 def->common.type = STMT_LED_NAME;
449 def->common.next = NULL;
450 def->merge = MERGE_DEFAULT;
453 def->virtual = virtual;
459 FreeInclude(IncludeStmt *incl);
462 IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
464 IncludeStmt *incl, *first;
470 stmt = strdup_safe(str);
473 char *file = NULL, *map = NULL, *extra_data = NULL;
475 if (!ParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
479 * Given an RMLVO (here layout) like 'us,,fr', the rules parser
480 * will give out something like 'pc+us+:2+fr:3+inet(evdev)'.
481 * We should just skip the ':2' in this case and leave it to the
482 * appropriate section to deal with the empty group.
492 first = incl = malloc(sizeof(*first));
494 incl->next_incl = malloc(sizeof(*first));
495 incl = incl->next_incl;
505 incl->common.type = STMT_INCLUDE;
506 incl->common.next = NULL;
511 incl->modifier = extra_data;
512 incl->next_incl = NULL;
515 merge = MERGE_AUGMENT;
517 merge = MERGE_OVERRIDE;
529 XKB_ERROR_INVALID_INCLUDE_STATEMENT,
530 "Illegal include statement \"%s\"; Ignored\n", stmt);
537 XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs,
538 enum xkb_map_flags flags)
542 file = calloc(1, sizeof(*file));
546 XkbEscapeMapName(name);
547 file->file_type = type;
548 file->name = name ? name : strdup("(unnamed)");
556 XkbFileFromComponents(struct xkb_context *ctx,
557 const struct xkb_component_names *kkctgs)
559 char *const components[] = {
560 kkctgs->keycodes, kkctgs->types,
561 kkctgs->compat, kkctgs->symbols,
563 enum xkb_file_type type;
564 IncludeStmt *include = NULL;
565 XkbFile *file = NULL;
566 ParseCommon *defs = NULL, *defsLast = NULL;
568 for (type = FIRST_KEYMAP_FILE_TYPE; type <= LAST_KEYMAP_FILE_TYPE; type++) {
569 include = IncludeCreate(ctx, components[type], MERGE_DEFAULT);
573 file = XkbFileCreate(type, NULL, (ParseCommon *) include, 0);
575 FreeInclude(include);
580 defsLast = defs = &file->common;
582 defsLast = defsLast->next = &file->common;
585 file = XkbFileCreate(FILE_TYPE_KEYMAP, NULL, defs, 0);
592 FreeXkbFile((XkbFile *) defs);
597 FreeExpr(ExprDef *expr)
602 switch (expr->expr.op) {
604 case EXPR_UNARY_PLUS:
607 FreeStmt((ParseCommon *) expr->unary.child);
615 FreeStmt((ParseCommon *) expr->binary.left);
616 FreeStmt((ParseCommon *) expr->binary.right);
619 case EXPR_ACTION_DECL:
620 FreeStmt((ParseCommon *) expr->action.args);
623 case EXPR_ACTION_LIST:
624 FreeStmt((ParseCommon *) expr->actions.actions);
628 FreeStmt((ParseCommon *) expr->array_ref.entry);
631 case EXPR_KEYSYM_LIST:
632 darray_free(expr->keysym_list.syms);
633 darray_free(expr->keysym_list.symsMapIndex);
634 darray_free(expr->keysym_list.symsNumEntries);
643 FreeInclude(IncludeStmt *incl)
649 next = incl->next_incl;
653 free(incl->modifier);
662 FreeStmt(ParseCommon *stmt)
670 switch (stmt->type) {
672 FreeInclude((IncludeStmt *) stmt);
673 /* stmt is already free'd here. */
677 FreeExpr((ExprDef *) stmt);
680 FreeStmt((ParseCommon *) ((VarDef *) stmt)->name);
681 FreeStmt((ParseCommon *) ((VarDef *) stmt)->value);
684 FreeStmt((ParseCommon *) ((KeyTypeDef *) stmt)->body);
687 FreeStmt((ParseCommon *) ((InterpDef *) stmt)->match);
688 FreeStmt((ParseCommon *) ((InterpDef *) stmt)->def);
691 FreeStmt((ParseCommon *) ((VModDef *) stmt)->value);
694 FreeStmt((ParseCommon *) ((SymbolsDef *) stmt)->symbols);
697 FreeStmt((ParseCommon *) ((ModMapDef *) stmt)->keys);
699 case STMT_GROUP_COMPAT:
700 FreeStmt((ParseCommon *) ((GroupCompatDef *) stmt)->def);
703 FreeStmt((ParseCommon *) ((LedMapDef *) stmt)->body);
706 FreeStmt((ParseCommon *) ((LedNameDef *) stmt)->name);
718 FreeXkbFile(XkbFile *file)
724 next = (XkbFile *) file->common.next;
726 switch (file->file_type) {
727 case FILE_TYPE_KEYMAP:
728 FreeXkbFile((XkbFile *) file->defs);
731 case FILE_TYPE_TYPES:
732 case FILE_TYPE_COMPAT:
733 case FILE_TYPE_SYMBOLS:
734 case FILE_TYPE_KEYCODES:
735 case FILE_TYPE_GEOMETRY:
736 FreeStmt(file->defs);
749 static const char *xkb_file_type_strings[_FILE_TYPE_NUM_ENTRIES] = {
750 [FILE_TYPE_KEYCODES] = "xkb_keycodes",
751 [FILE_TYPE_TYPES] = "xkb_types",
752 [FILE_TYPE_COMPAT] = "xkb_compatibility",
753 [FILE_TYPE_SYMBOLS] = "xkb_symbols",
754 [FILE_TYPE_GEOMETRY] = "xkb_geometry",
755 [FILE_TYPE_KEYMAP] = "xkb_keymap",
756 [FILE_TYPE_RULES] = "rules",
760 xkb_file_type_to_string(enum xkb_file_type type)
762 if (type >= _FILE_TYPE_NUM_ENTRIES)
764 return xkb_file_type_strings[type];
767 static const char *stmt_type_strings[_STMT_NUM_VALUES] = {
768 [STMT_UNKNOWN] = "unknown statement",
769 [STMT_INCLUDE] = "include statement",
770 [STMT_KEYCODE] = "key name definition",
771 [STMT_ALIAS] = "key alias definition",
772 [STMT_EXPR] = "expression",
773 [STMT_VAR] = "variable definition",
774 [STMT_TYPE] = "key type definition",
775 [STMT_INTERP] = "symbol interpretation definition",
776 [STMT_VMOD] = "virtual modifiers definition",
777 [STMT_SYMBOLS] = "key symbols definition",
778 [STMT_MODMAP] = "modifier map declaration",
779 [STMT_GROUP_COMPAT] = "group declaration",
780 [STMT_LED_MAP] = "indicator map declaration",
781 [STMT_LED_NAME] = "indicator name declaration",
785 stmt_type_to_string(enum stmt_type type)
787 if (type >= _STMT_NUM_VALUES)
789 return stmt_type_strings[type];
792 static const char *expr_op_type_strings[_EXPR_NUM_VALUES] = {
793 [EXPR_VALUE] = "literal",
794 [EXPR_IDENT] = "identifier",
795 [EXPR_ACTION_DECL] = "action declaration",
796 [EXPR_FIELD_REF] = "field reference",
797 [EXPR_ARRAY_REF] = "array reference",
798 [EXPR_KEYSYM_LIST] = "list of keysyms",
799 [EXPR_ACTION_LIST] = "list of actions",
800 [EXPR_ADD] = "addition",
801 [EXPR_SUBTRACT] = "subtraction",
802 [EXPR_MULTIPLY] = "multiplication",
803 [EXPR_DIVIDE] = "division",
804 [EXPR_ASSIGN] = "assignment",
805 [EXPR_NOT] = "logical negation",
806 [EXPR_NEGATE] = "arithmetic negation",
807 [EXPR_INVERT] = "bitwise inversion",
808 [EXPR_UNARY_PLUS] = "unary plus",
812 expr_op_type_to_string(enum expr_op_type type)
814 if (type >= _EXPR_NUM_VALUES)
816 return expr_op_type_strings[type];
819 static const char *expr_value_type_strings[_EXPR_TYPE_NUM_VALUES] = {
820 [EXPR_TYPE_UNKNOWN] = "unknown",
821 [EXPR_TYPE_BOOLEAN] = "boolean",
822 [EXPR_TYPE_INT] = "int",
823 [EXPR_TYPE_FLOAT] = "float",
824 [EXPR_TYPE_STRING] = "string",
825 [EXPR_TYPE_ACTION] = "action",
826 [EXPR_TYPE_ACTIONS] = "actions",
827 [EXPR_TYPE_KEYNAME] = "keyname",
828 [EXPR_TYPE_SYMBOLS] = "symbols",
832 expr_value_type_to_string(enum expr_value_type type)
834 if (type >= _EXPR_TYPE_NUM_VALUES)
836 return expr_value_type_strings[type];