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"
59 ATTR_MALLOC static void *
60 malloc_or_die(size_t size)
62 void *p = malloc(size);
64 fprintf(stderr, "Out of memory\n");
71 AppendStmt(ParseCommon *to, ParseCommon *append)
78 for (iter = to; iter->next; iter = iter->next);
85 ExprCreate(enum expr_op_type op, enum expr_value_type type)
89 expr = malloc_or_die(sizeof(*expr));
91 expr->common.type = STMT_EXPR;
92 expr->common.next = NULL;
94 expr->value_type = type;
99 ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
103 expr = malloc_or_die(sizeof(*expr));
105 expr->common.type = STMT_EXPR;
106 expr->common.next = NULL;
108 expr->value_type = type;
109 expr->value.child = child;
114 ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
118 expr = malloc_or_die(sizeof(*expr));
120 expr->common.type = STMT_EXPR;
121 expr->common.next = NULL;
123 if (op == EXPR_ASSIGN || left->value_type == EXPR_TYPE_UNKNOWN)
124 expr->value_type = right->value_type;
125 else if (left->value_type == right->value_type ||
126 right->value_type == EXPR_TYPE_UNKNOWN)
127 expr->value_type = left->value_type;
129 expr->value_type = EXPR_TYPE_UNKNOWN;
130 expr->value.binary.left = left;
131 expr->value.binary.right = right;
136 KeycodeCreate(xkb_atom_t name, int64_t value)
140 def = malloc_or_die(sizeof(*def));
142 def->common.type = STMT_KEYCODE;
143 def->common.next = NULL;
150 KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real)
154 def = malloc_or_die(sizeof(*def));
156 def->common.type = STMT_ALIAS;
157 def->common.next = NULL;
164 VModCreate(xkb_atom_t name, ExprDef * value)
168 def = malloc_or_die(sizeof(*def));
170 def->common.type = STMT_VMOD;
171 def->common.next = NULL;
178 VarCreate(ExprDef * name, ExprDef * value)
181 def = malloc_or_die(sizeof(*def));
183 def->common.type = STMT_VAR;
184 def->common.next = NULL;
191 BoolVarCreate(xkb_atom_t nameToken, unsigned set)
193 ExprDef *name, *value;
195 name = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
196 name->value.str = nameToken;
197 value = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN);
198 value->value.uval = set;
199 return VarCreate(name, value);
203 InterpCreate(char *sym, ExprDef * match)
207 def = malloc_or_die(sizeof(*def));
209 def->common.type = STMT_INTERP;
210 def->common.next = NULL;
217 KeyTypeCreate(xkb_atom_t name, VarDef * body)
221 def = malloc_or_die(sizeof(*def));
223 def->common.type = STMT_TYPE;
224 def->common.next = NULL;
225 def->merge = MERGE_DEFAULT;
232 SymbolsCreate(xkb_atom_t keyName, ExprDef *symbols)
236 def = malloc_or_die(sizeof(*def));
238 def->common.type = STMT_SYMBOLS;
239 def->common.next = NULL;
240 def->merge = MERGE_DEFAULT;
241 def->keyName = keyName;
242 def->symbols = symbols;
247 GroupCompatCreate(int group, ExprDef * val)
251 def = malloc_or_die(sizeof(*def));
253 def->common.type = STMT_GROUP_COMPAT;
254 def->common.next = NULL;
255 def->merge = MERGE_DEFAULT;
262 ModMapCreate(uint32_t modifier, ExprDef * keys)
266 def = malloc_or_die(sizeof(*def));
268 def->common.type = STMT_MODMAP;
269 def->common.next = NULL;
270 def->merge = MERGE_DEFAULT;
271 def->modifier = modifier;
277 LedMapCreate(xkb_atom_t name, VarDef * body)
281 def = malloc_or_die(sizeof(*def));
283 def->common.type = STMT_LED_MAP;
284 def->common.next = NULL;
285 def->merge = MERGE_DEFAULT;
292 LedNameCreate(int ndx, ExprDef * name, bool virtual)
296 def = malloc_or_die(sizeof(*def));
298 def->common.type = STMT_LED_NAME;
299 def->common.next = NULL;
300 def->merge = MERGE_DEFAULT;
303 def->virtual = virtual;
308 ActionCreate(xkb_atom_t name, ExprDef * args)
312 act = malloc_or_die(sizeof(*act));
314 act->common.type = STMT_EXPR;
315 act->common.next = NULL;
316 act->op = EXPR_ACTION_DECL;
317 act->value.action.name = name;
318 act->value.action.args = args;
323 CreateKeysymList(char *sym)
327 def = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
329 darray_init(def->value.list.syms);
330 darray_init(def->value.list.symsMapIndex);
331 darray_init(def->value.list.symsNumEntries);
333 darray_append(def->value.list.syms, sym);
334 darray_append(def->value.list.symsMapIndex, 0);
335 darray_append(def->value.list.symsNumEntries, 1);
341 CreateMultiKeysymList(ExprDef *list)
343 size_t nLevels = darray_size(list->value.list.symsMapIndex);
345 darray_resize(list->value.list.symsMapIndex, 1);
346 darray_resize(list->value.list.symsNumEntries, 1);
347 darray_item(list->value.list.symsMapIndex, 0) = 0;
348 darray_item(list->value.list.symsNumEntries, 0) = nLevels;
354 AppendKeysymList(ExprDef * list, char *sym)
356 size_t nSyms = darray_size(list->value.list.syms);
358 darray_append(list->value.list.symsMapIndex, nSyms);
359 darray_append(list->value.list.symsNumEntries, 1);
360 darray_append(list->value.list.syms, sym);
366 AppendMultiKeysymList(ExprDef * list, ExprDef * append)
368 size_t nSyms = darray_size(list->value.list.syms);
369 size_t numEntries = darray_size(append->value.list.syms);
371 darray_append(list->value.list.symsMapIndex, nSyms);
372 darray_append(list->value.list.symsNumEntries, numEntries);
373 darray_append_items(list->value.list.syms,
374 darray_mem(append->value.list.syms, 0),
377 darray_resize(append->value.list.syms, 0);
378 FreeStmt(&append->common);
384 FreeInclude(IncludeStmt *incl);
387 IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
389 IncludeStmt *incl, *first;
390 char *file, *map, *stmt, *tmp, *extra_data;
396 stmt = strdup_safe(str);
399 if (!ParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
403 * Given an RMLVO (here layout) like 'us,,fr', the rules parser
404 * will give out something like 'pc+us+:2+fr:3+inet(evdev)'.
405 * We should just skip the ':2' in this case and leave it to the
406 * appropriate section to deal with the empty group.
416 first = incl = malloc(sizeof(*first));
418 incl->next_incl = malloc(sizeof(*first));
419 incl = incl->next_incl;
424 "Allocation failure in IncludeCreate; "
425 "Using only part of the include\n");
429 incl->common.type = STMT_INCLUDE;
430 incl->common.next = NULL;
435 incl->modifier = extra_data;
436 incl->next_incl = NULL;
439 merge = MERGE_AUGMENT;
441 merge = MERGE_OVERRIDE;
452 log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt);
459 * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
462 static const unsigned char componentSpecLegal[] = {
463 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
464 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
470 EnsureSafeMapName(char *name)
475 while (*name != '\0') {
476 if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0)
483 XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
484 ParseCommon *defs, enum xkb_map_flags flags)
488 file = calloc(1, sizeof(*file));
492 EnsureSafeMapName(name);
493 file->file_type = type;
494 file->topName = strdup_safe(name);
497 file->id = xkb_context_take_file_id(ctx);
503 XkbFileFromComponents(struct xkb_context *ctx,
504 const struct xkb_component_names *kkctgs)
507 XkbFile *keycodes, *types, *compat, *symbols;
509 inc = IncludeCreate(ctx, kkctgs->keycodes, MERGE_DEFAULT);
510 keycodes = XkbFileCreate(ctx, FILE_TYPE_KEYCODES, NULL,
511 (ParseCommon *) inc, 0);
513 inc = IncludeCreate(ctx, kkctgs->types, MERGE_DEFAULT);
514 types = XkbFileCreate(ctx, FILE_TYPE_TYPES, NULL,
515 (ParseCommon *) inc, 0);
516 AppendStmt(&keycodes->common, &types->common);
518 inc = IncludeCreate(ctx, kkctgs->compat, MERGE_DEFAULT);
519 compat = XkbFileCreate(ctx, FILE_TYPE_COMPAT, NULL,
520 (ParseCommon *) inc, 0);
521 AppendStmt(&keycodes->common, &compat->common);
523 inc = IncludeCreate(ctx, kkctgs->symbols, MERGE_DEFAULT);
524 symbols = XkbFileCreate(ctx, FILE_TYPE_SYMBOLS, NULL,
525 (ParseCommon *) inc, 0);
526 AppendStmt(&keycodes->common, &symbols->common);
528 return XkbFileCreate(ctx, FILE_TYPE_KEYMAP, NULL,
529 &keycodes->common, 0);
533 FreeExpr(ExprDef *expr)
541 case EXPR_ACTION_LIST:
543 case EXPR_UNARY_PLUS:
546 FreeStmt(&expr->value.child->common);
554 FreeStmt(&expr->value.binary.left->common);
555 FreeStmt(&expr->value.binary.right->common);
558 case EXPR_ACTION_DECL:
559 FreeStmt(&expr->value.action.args->common);
563 FreeStmt(&expr->value.array.entry->common);
566 case EXPR_KEYSYM_LIST:
567 darray_foreach(sym, expr->value.list.syms)
569 darray_free(expr->value.list.syms);
570 darray_free(expr->value.list.symsMapIndex);
571 darray_free(expr->value.list.symsNumEntries);
580 FreeInclude(IncludeStmt *incl)
586 next = incl->next_incl;
590 free(incl->modifier);
599 FreeStmt(ParseCommon *stmt)
609 switch (stmt->type) {
611 FreeInclude((IncludeStmt *) stmt);
612 /* stmt is already free'd here. */
619 FreeStmt(&u.var->name->common);
620 FreeStmt(&u.var->value->common);
623 FreeStmt(&u.keyType->body->common);
627 FreeStmt(&u.interp->match->common);
628 FreeStmt(&u.interp->def->common);
631 FreeStmt(&u.vmod->value->common);
634 FreeStmt(&u.syms->symbols->common);
637 FreeStmt(&u.modMask->keys->common);
639 case STMT_GROUP_COMPAT:
640 FreeStmt(&u.groupCompat->def->common);
643 FreeStmt(&u.ledMap->body->common);
646 FreeStmt(&u.ledName->name->common);
658 FreeXkbFile(XkbFile *file)
664 next = (XkbFile *) file->common.next;
666 switch (file->file_type) {
667 case FILE_TYPE_KEYMAP:
668 FreeXkbFile((XkbFile *) file->defs);
671 case FILE_TYPE_TYPES:
672 case FILE_TYPE_COMPAT:
673 case FILE_TYPE_SYMBOLS:
674 case FILE_TYPE_KEYCODES:
675 case FILE_TYPE_GEOMETRY:
676 FreeStmt(file->defs);
690 static const char *xkb_file_type_strings[_FILE_TYPE_NUM_ENTRIES] = {
691 [FILE_TYPE_KEYCODES] = "xkb_keycodes",
692 [FILE_TYPE_TYPES] = "xkb_types",
693 [FILE_TYPE_COMPAT] = "xkb_compatibility",
694 [FILE_TYPE_SYMBOLS] = "xkb_symbols",
695 [FILE_TYPE_KEYMAP] = "xkb_keymap",
696 [FILE_TYPE_RULES] = "rules",
700 xkb_file_type_to_string(enum xkb_file_type type)
702 if (type > _FILE_TYPE_NUM_ENTRIES)
704 return xkb_file_type_strings[type];
707 static const char *stmt_type_strings[_STMT_NUM_VALUES] = {
708 [STMT_UNKNOWN] = "unknown statement",
709 [STMT_INCLUDE] = "include statement",
710 [STMT_KEYCODE] = "key name definition",
711 [STMT_ALIAS] = "key alias definition",
712 [STMT_EXPR] = "expression",
713 [STMT_VAR] = "variable definition",
714 [STMT_TYPE] = "key type definition",
715 [STMT_INTERP] = "symbol interpretation definition",
716 [STMT_VMOD] = "virtual modifiers definition",
717 [STMT_SYMBOLS] = "key symbols definition",
718 [STMT_MODMAP] = "modifier map declaration",
719 [STMT_GROUP_COMPAT] = "group declaration",
720 [STMT_LED_MAP] = "indicator map declaration",
721 [STMT_LED_NAME] = "indicator name declaration",
725 stmt_type_to_string(enum stmt_type type)
727 if (type >= _STMT_NUM_VALUES)
729 return stmt_type_strings[type];
732 static const char *expr_op_type_strings[_EXPR_NUM_VALUES] = {
733 [EXPR_VALUE] = "literal",
734 [EXPR_IDENT] = "identifier",
735 [EXPR_ACTION_DECL] = "action declaration",
736 [EXPR_FIELD_REF] = "field reference",
737 [EXPR_ARRAY_REF] = "array reference",
738 [EXPR_KEYSYM_LIST] = "list of keysyms",
739 [EXPR_ACTION_LIST] = "list of actions",
740 [EXPR_ADD] = "addition",
741 [EXPR_SUBTRACT] = "subtraction",
742 [EXPR_MULTIPLY] = "multiplication",
743 [EXPR_DIVIDE] = "division",
744 [EXPR_ASSIGN] = "assignment",
745 [EXPR_NOT] = "logical negation",
746 [EXPR_NEGATE] = "arithmetic negation",
747 [EXPR_INVERT] = "bitwise inversion",
748 [EXPR_UNARY_PLUS] = "unary plus",
752 expr_op_type_to_string(enum expr_op_type type)
754 if (type >= _EXPR_NUM_VALUES)
756 return expr_op_type_strings[type];
759 static const char *expr_value_type_strings[_EXPR_TYPE_NUM_VALUES] = {
760 [EXPR_TYPE_UNKNOWN] = "unknown",
761 [EXPR_TYPE_BOOLEAN] = "boolean",
762 [EXPR_TYPE_INT] = "int",
763 [EXPR_TYPE_STRING] = "string",
764 [EXPR_TYPE_ACTION] = "action",
765 [EXPR_TYPE_KEYNAME] = "keyname",
766 [EXPR_TYPE_SYMBOLS] = "symbols",
770 expr_value_type_to_string(enum expr_value_type type)
772 if (type >= _EXPR_TYPE_NUM_VALUES)
774 return expr_value_type_strings[type];