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>
54 #include "xkbcomp-priv.h"
55 #include "ast-build.h"
56 #include "parser-priv.h"
60 AppendStmt(ParseCommon *to, ParseCommon *append)
67 for (iter = to; iter->next; iter = iter->next);
74 ExprCreate(enum expr_op_type op, enum expr_value_type type)
76 ExprDef *expr = malloc(sizeof(*expr));
80 expr->common.type = STMT_EXPR;
81 expr->common.next = NULL;
83 expr->value_type = type;
89 ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
92 ExprDef *expr = malloc(sizeof(*expr));
96 expr->common.type = STMT_EXPR;
97 expr->common.next = NULL;
99 expr->value_type = type;
100 expr->value.child = child;
106 ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
108 ExprDef *expr = malloc(sizeof(*expr));
112 expr->common.type = STMT_EXPR;
113 expr->common.next = NULL;
115 if (op == EXPR_ASSIGN || left->value_type == EXPR_TYPE_UNKNOWN)
116 expr->value_type = right->value_type;
117 else if (left->value_type == right->value_type ||
118 right->value_type == EXPR_TYPE_UNKNOWN)
119 expr->value_type = left->value_type;
121 expr->value_type = EXPR_TYPE_UNKNOWN;
122 expr->value.binary.left = left;
123 expr->value.binary.right = right;
129 KeycodeCreate(xkb_atom_t name, int64_t value)
131 KeycodeDef *def = malloc(sizeof(*def));
135 def->common.type = STMT_KEYCODE;
136 def->common.next = NULL;
144 KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real)
146 KeyAliasDef *def = malloc(sizeof(*def));
150 def->common.type = STMT_ALIAS;
151 def->common.next = NULL;
159 VModCreate(xkb_atom_t name, ExprDef *value)
161 VModDef *def = malloc(sizeof(*def));
165 def->common.type = STMT_VMOD;
166 def->common.next = NULL;
174 VarCreate(ExprDef *name, ExprDef *value)
176 VarDef *def = malloc(sizeof(*def));
180 def->common.type = STMT_VAR;
181 def->common.next = NULL;
189 BoolVarCreate(xkb_atom_t nameToken, unsigned set)
191 ExprDef *name, *value;
194 name = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
195 name->value.str = nameToken;
196 value = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN);
197 value->value.uval = set;
198 def = VarCreate(name, value);
204 InterpCreate(char *sym, ExprDef *match)
206 InterpDef *def = malloc(sizeof(*def));
210 def->common.type = STMT_INTERP;
211 def->common.next = NULL;
219 KeyTypeCreate(xkb_atom_t name, VarDef *body)
221 KeyTypeDef *def = malloc(sizeof(*def));
225 def->common.type = STMT_TYPE;
226 def->common.next = NULL;
227 def->merge = MERGE_DEFAULT;
235 SymbolsCreate(xkb_atom_t keyName, ExprDef *symbols)
237 SymbolsDef *def = malloc(sizeof(*def));
241 def->common.type = STMT_SYMBOLS;
242 def->common.next = NULL;
243 def->merge = MERGE_DEFAULT;
244 def->keyName = keyName;
245 def->symbols = symbols;
251 GroupCompatCreate(int group, ExprDef *val)
253 GroupCompatDef *def = malloc(sizeof(*def));
257 def->common.type = STMT_GROUP_COMPAT;
258 def->common.next = NULL;
259 def->merge = MERGE_DEFAULT;
267 ModMapCreate(uint32_t modifier, ExprDef *keys)
269 ModMapDef *def = malloc(sizeof(*def));
273 def->common.type = STMT_MODMAP;
274 def->common.next = NULL;
275 def->merge = MERGE_DEFAULT;
276 def->modifier = modifier;
283 LedMapCreate(xkb_atom_t name, VarDef *body)
285 LedMapDef *def = malloc(sizeof(*def));
289 def->common.type = STMT_LED_MAP;
290 def->common.next = NULL;
291 def->merge = MERGE_DEFAULT;
299 LedNameCreate(int ndx, ExprDef *name, bool virtual)
301 LedNameDef *def = malloc(sizeof(*def));
305 def->common.type = STMT_LED_NAME;
306 def->common.next = NULL;
307 def->merge = MERGE_DEFAULT;
310 def->virtual = virtual;
316 ActionCreate(xkb_atom_t name, ExprDef *args)
318 ExprDef *act = malloc(sizeof(*act));
322 act->common.type = STMT_EXPR;
323 act->common.next = NULL;
324 act->op = EXPR_ACTION_DECL;
325 act->value.action.name = name;
326 act->value.action.args = args;
332 CreateKeysymList(char *sym)
336 def = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
338 darray_init(def->value.list.syms);
339 darray_init(def->value.list.symsMapIndex);
340 darray_init(def->value.list.symsNumEntries);
342 darray_append(def->value.list.syms, sym);
343 darray_append(def->value.list.symsMapIndex, 0);
344 darray_append(def->value.list.symsNumEntries, 1);
350 CreateMultiKeysymList(ExprDef *list)
352 size_t nLevels = darray_size(list->value.list.symsMapIndex);
354 darray_resize(list->value.list.symsMapIndex, 1);
355 darray_resize(list->value.list.symsNumEntries, 1);
356 darray_item(list->value.list.symsMapIndex, 0) = 0;
357 darray_item(list->value.list.symsNumEntries, 0) = nLevels;
363 AppendKeysymList(ExprDef *list, char *sym)
365 size_t nSyms = darray_size(list->value.list.syms);
367 darray_append(list->value.list.symsMapIndex, nSyms);
368 darray_append(list->value.list.symsNumEntries, 1);
369 darray_append(list->value.list.syms, sym);
375 AppendMultiKeysymList(ExprDef *list, ExprDef *append)
377 size_t nSyms = darray_size(list->value.list.syms);
378 size_t numEntries = darray_size(append->value.list.syms);
380 darray_append(list->value.list.symsMapIndex, nSyms);
381 darray_append(list->value.list.symsNumEntries, numEntries);
382 darray_append_items(list->value.list.syms,
383 darray_mem(append->value.list.syms, 0),
386 darray_resize(append->value.list.syms, 0);
387 FreeStmt(&append->common);
393 FreeInclude(IncludeStmt *incl);
396 IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
398 IncludeStmt *incl, *first;
399 char *file, *map, *stmt, *tmp, *extra_data;
405 stmt = strdup_safe(str);
408 if (!ParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
412 * Given an RMLVO (here layout) like 'us,,fr', the rules parser
413 * will give out something like 'pc+us+:2+fr:3+inet(evdev)'.
414 * We should just skip the ':2' in this case and leave it to the
415 * appropriate section to deal with the empty group.
425 first = incl = malloc(sizeof(*first));
427 incl->next_incl = malloc(sizeof(*first));
428 incl = incl->next_incl;
433 "Allocation failure in IncludeCreate; "
434 "Using only part of the include\n");
438 incl->common.type = STMT_INCLUDE;
439 incl->common.next = NULL;
444 incl->modifier = extra_data;
445 incl->next_incl = NULL;
448 merge = MERGE_AUGMENT;
450 merge = MERGE_OVERRIDE;
461 log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt);
468 XkbEscapeMapName(char *name)
471 * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
474 static const unsigned char legal[] = {
475 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
476 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
485 if (!(legal[*name / 8] & (1 << (*name % 8))))
492 XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
493 ParseCommon *defs, enum xkb_map_flags flags)
497 file = calloc(1, sizeof(*file));
501 XkbEscapeMapName(name);
502 file->file_type = type;
503 file->topName = strdup_safe(name);
512 XkbFileFromComponents(struct xkb_context *ctx,
513 const struct xkb_component_names *kkctgs)
515 char *const components[] = {
516 kkctgs->keycodes, kkctgs->types,
517 kkctgs->compat, kkctgs->symbols,
519 enum xkb_file_type type;
520 IncludeStmt *include = NULL;
521 XkbFile *file = NULL;
522 ParseCommon *defs = NULL;
524 for (type = FIRST_KEYMAP_FILE_TYPE; type <= LAST_KEYMAP_FILE_TYPE; type++) {
525 include = IncludeCreate(ctx, components[type], MERGE_DEFAULT);
529 file = XkbFileCreate(ctx, type, NULL, &include->common, 0);
531 FreeInclude(include);
535 defs = AppendStmt(defs, &file->common);
538 file = XkbFileCreate(ctx, FILE_TYPE_KEYMAP, NULL, defs, 0);
545 FreeXkbFile((XkbFile *) defs);
550 FreeExpr(ExprDef *expr)
558 case EXPR_ACTION_LIST:
560 case EXPR_UNARY_PLUS:
563 FreeStmt(&expr->value.child->common);
571 FreeStmt(&expr->value.binary.left->common);
572 FreeStmt(&expr->value.binary.right->common);
575 case EXPR_ACTION_DECL:
576 FreeStmt(&expr->value.action.args->common);
580 FreeStmt(&expr->value.array.entry->common);
583 case EXPR_KEYSYM_LIST:
584 darray_foreach(sym, expr->value.list.syms)
586 darray_free(expr->value.list.syms);
587 darray_free(expr->value.list.symsMapIndex);
588 darray_free(expr->value.list.symsNumEntries);
597 FreeInclude(IncludeStmt *incl)
603 next = incl->next_incl;
607 free(incl->modifier);
616 FreeStmt(ParseCommon *stmt)
626 switch (stmt->type) {
628 FreeInclude((IncludeStmt *) stmt);
629 /* stmt is already free'd here. */
636 FreeStmt(&u.var->name->common);
637 FreeStmt(&u.var->value->common);
640 FreeStmt(&u.keyType->body->common);
644 FreeStmt(&u.interp->match->common);
645 FreeStmt(&u.interp->def->common);
648 FreeStmt(&u.vmod->value->common);
651 FreeStmt(&u.syms->symbols->common);
654 FreeStmt(&u.modMask->keys->common);
656 case STMT_GROUP_COMPAT:
657 FreeStmt(&u.groupCompat->def->common);
660 FreeStmt(&u.ledMap->body->common);
663 FreeStmt(&u.ledName->name->common);
675 FreeXkbFile(XkbFile *file)
681 next = (XkbFile *) file->common.next;
683 switch (file->file_type) {
684 case FILE_TYPE_KEYMAP:
685 FreeXkbFile((XkbFile *) file->defs);
688 case FILE_TYPE_TYPES:
689 case FILE_TYPE_COMPAT:
690 case FILE_TYPE_SYMBOLS:
691 case FILE_TYPE_KEYCODES:
692 case FILE_TYPE_GEOMETRY:
693 FreeStmt(file->defs);
707 static const char *xkb_file_type_strings[_FILE_TYPE_NUM_ENTRIES] = {
708 [FILE_TYPE_KEYCODES] = "xkb_keycodes",
709 [FILE_TYPE_TYPES] = "xkb_types",
710 [FILE_TYPE_COMPAT] = "xkb_compatibility",
711 [FILE_TYPE_SYMBOLS] = "xkb_symbols",
712 [FILE_TYPE_GEOMETRY] = "xkb_geometry",
713 [FILE_TYPE_KEYMAP] = "xkb_keymap",
714 [FILE_TYPE_RULES] = "rules",
718 xkb_file_type_to_string(enum xkb_file_type type)
720 if (type > _FILE_TYPE_NUM_ENTRIES)
722 return xkb_file_type_strings[type];
725 static const char *stmt_type_strings[_STMT_NUM_VALUES] = {
726 [STMT_UNKNOWN] = "unknown statement",
727 [STMT_INCLUDE] = "include statement",
728 [STMT_KEYCODE] = "key name definition",
729 [STMT_ALIAS] = "key alias definition",
730 [STMT_EXPR] = "expression",
731 [STMT_VAR] = "variable definition",
732 [STMT_TYPE] = "key type definition",
733 [STMT_INTERP] = "symbol interpretation definition",
734 [STMT_VMOD] = "virtual modifiers definition",
735 [STMT_SYMBOLS] = "key symbols definition",
736 [STMT_MODMAP] = "modifier map declaration",
737 [STMT_GROUP_COMPAT] = "group declaration",
738 [STMT_LED_MAP] = "indicator map declaration",
739 [STMT_LED_NAME] = "indicator name declaration",
743 stmt_type_to_string(enum stmt_type type)
745 if (type >= _STMT_NUM_VALUES)
747 return stmt_type_strings[type];
750 static const char *expr_op_type_strings[_EXPR_NUM_VALUES] = {
751 [EXPR_VALUE] = "literal",
752 [EXPR_IDENT] = "identifier",
753 [EXPR_ACTION_DECL] = "action declaration",
754 [EXPR_FIELD_REF] = "field reference",
755 [EXPR_ARRAY_REF] = "array reference",
756 [EXPR_KEYSYM_LIST] = "list of keysyms",
757 [EXPR_ACTION_LIST] = "list of actions",
758 [EXPR_ADD] = "addition",
759 [EXPR_SUBTRACT] = "subtraction",
760 [EXPR_MULTIPLY] = "multiplication",
761 [EXPR_DIVIDE] = "division",
762 [EXPR_ASSIGN] = "assignment",
763 [EXPR_NOT] = "logical negation",
764 [EXPR_NEGATE] = "arithmetic negation",
765 [EXPR_INVERT] = "bitwise inversion",
766 [EXPR_UNARY_PLUS] = "unary plus",
770 expr_op_type_to_string(enum expr_op_type type)
772 if (type >= _EXPR_NUM_VALUES)
774 return expr_op_type_strings[type];
777 static const char *expr_value_type_strings[_EXPR_TYPE_NUM_VALUES] = {
778 [EXPR_TYPE_UNKNOWN] = "unknown",
779 [EXPR_TYPE_BOOLEAN] = "boolean",
780 [EXPR_TYPE_INT] = "int",
781 [EXPR_TYPE_STRING] = "string",
782 [EXPR_TYPE_ACTION] = "action",
783 [EXPR_TYPE_KEYNAME] = "keyname",
784 [EXPR_TYPE_SYMBOLS] = "symbols",
788 expr_value_type_to_string(enum expr_value_type type)
790 if (type >= _EXPR_TYPE_NUM_VALUES)
792 return expr_value_type_strings[type];