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 ********************************************************/
27 #include "parseutils.h"
30 ATTR_MALLOC static void *
31 malloc_or_die(size_t size)
33 void *p = malloc(size);
35 fprintf(stderr, "Out of memory\n");
42 AppendStmt(ParseCommon * to, ParseCommon * append)
44 ParseCommon *start = to;
48 while ((to != NULL) && (to->next != NULL))
60 ExprCreate(enum expr_op_type op, enum expr_value_type type)
64 expr = malloc_or_die(sizeof(*expr));
66 expr->common.type = STMT_EXPR;
67 expr->common.next = NULL;
69 expr->value_type = type;
74 ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
78 expr = malloc_or_die(sizeof(*expr));
80 expr->common.type = STMT_EXPR;
81 expr->common.next = NULL;
83 expr->value_type = type;
84 expr->value.child = child;
89 ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
93 expr = malloc_or_die(sizeof(*expr));
95 expr->common.type = STMT_EXPR;
96 expr->common.next = NULL;
98 if (op == EXPR_ASSIGN || left->value_type == EXPR_TYPE_UNKNOWN)
99 expr->value_type = right->value_type;
100 else if (left->value_type == right->value_type ||
101 right->value_type == EXPR_TYPE_UNKNOWN)
102 expr->value_type = left->value_type;
104 expr->value_type = EXPR_TYPE_UNKNOWN;
105 expr->value.binary.left = left;
106 expr->value.binary.right = right;
111 KeycodeCreate(char keyName[XkbKeyNameLength], unsigned long value)
115 def = malloc_or_die(sizeof(*def));
117 def->common.type = STMT_KEYCODE;
118 def->common.next = NULL;
119 strncpy(def->name, keyName, XkbKeyNameLength);
125 KeyAliasCreate(char alias[XkbKeyNameLength], char real[XkbKeyNameLength])
129 def = malloc_or_die(sizeof(*def));
131 def->common.type = STMT_ALIAS;
132 def->common.next = NULL;
133 strncpy(def->alias, alias, XkbKeyNameLength);
134 strncpy(def->real, real, XkbKeyNameLength);
139 VModCreate(xkb_atom_t name, ExprDef * value)
143 def = malloc_or_die(sizeof(*def));
145 def->common.type = STMT_VMOD;
146 def->common.next = NULL;
153 VarCreate(ExprDef * name, ExprDef * value)
156 def = malloc_or_die(sizeof(*def));
158 def->common.type = STMT_VAR;
159 def->common.next = NULL;
166 BoolVarCreate(xkb_atom_t nameToken, unsigned set)
168 ExprDef *name, *value;
170 name = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
171 name->value.str = nameToken;
172 value = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN);
173 value->value.uval = set;
174 return VarCreate(name, value);
178 InterpCreate(char *sym, ExprDef * match)
182 def = malloc_or_die(sizeof(*def));
184 def->common.type = STMT_INTERP;
185 def->common.next = NULL;
192 KeyTypeCreate(xkb_atom_t name, VarDef * body)
196 def = malloc_or_die(sizeof(*def));
198 def->common.type = STMT_TYPE;
199 def->common.next = NULL;
200 def->merge = MERGE_DEFAULT;
207 SymbolsCreate(char keyName[XkbKeyNameLength], ExprDef *symbols)
211 def = malloc_or_die(sizeof(*def));
213 def->common.type = STMT_SYMBOLS;
214 def->common.next = NULL;
215 def->merge = MERGE_DEFAULT;
216 strncpy(def->keyName, keyName, XkbKeyNameLength);
217 def->symbols = symbols;
222 GroupCompatCreate(int group, ExprDef * val)
226 def = malloc_or_die(sizeof(*def));
228 def->common.type = STMT_GROUP_COMPAT;
229 def->common.next = NULL;
230 def->merge = MERGE_DEFAULT;
237 ModMapCreate(uint32_t modifier, ExprDef * keys)
241 def = malloc_or_die(sizeof(*def));
243 def->common.type = STMT_MODMAP;
244 def->common.next = NULL;
245 def->merge = MERGE_DEFAULT;
246 def->modifier = modifier;
252 IndicatorMapCreate(xkb_atom_t name, VarDef * body)
254 IndicatorMapDef *def;
256 def = malloc_or_die(sizeof(*def));
258 def->common.type = STMT_INDICATOR_MAP;
259 def->common.next = NULL;
260 def->merge = MERGE_DEFAULT;
267 IndicatorNameCreate(int ndx, ExprDef * name, bool virtual)
269 IndicatorNameDef *def;
271 def = malloc_or_die(sizeof(*def));
273 def->common.type = STMT_INDICATOR_NAME;
274 def->common.next = NULL;
275 def->merge = MERGE_DEFAULT;
278 def->virtual = virtual;
283 ActionCreate(xkb_atom_t name, ExprDef * args)
287 act = malloc_or_die(sizeof(*act));
289 act->common.type = STMT_EXPR;
290 act->common.next = NULL;
291 act->op = EXPR_ACTION_DECL;
292 act->value.action.name = name;
293 act->value.action.args = args;
298 CreateKeysymList(char *sym)
302 def = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
304 darray_init(def->value.list.syms);
305 darray_init(def->value.list.symsMapIndex);
306 darray_init(def->value.list.symsNumEntries);
308 darray_append(def->value.list.syms, sym);
309 darray_append(def->value.list.symsMapIndex, 0);
310 darray_append(def->value.list.symsNumEntries, 1);
316 CreateMultiKeysymList(ExprDef *list)
318 size_t nLevels = darray_size(list->value.list.symsMapIndex);
320 darray_resize(list->value.list.symsMapIndex, 1);
321 darray_resize(list->value.list.symsNumEntries, 1);
322 darray_item(list->value.list.symsMapIndex, 0) = 0;
323 darray_item(list->value.list.symsNumEntries, 0) = nLevels;
329 AppendKeysymList(ExprDef * list, char *sym)
331 size_t nSyms = darray_size(list->value.list.syms);
333 darray_append(list->value.list.symsMapIndex, nSyms);
334 darray_append(list->value.list.symsNumEntries, 1);
335 darray_append(list->value.list.syms, sym);
341 AppendMultiKeysymList(ExprDef * list, ExprDef * append)
343 size_t nSyms = darray_size(list->value.list.syms);
344 size_t numEntries = darray_size(append->value.list.syms);
346 darray_append(list->value.list.symsMapIndex, nSyms);
347 darray_append(list->value.list.symsNumEntries, numEntries);
348 darray_append_items(list->value.list.syms,
349 darray_mem(append->value.list.syms, 0),
352 darray_resize(append->value.list.syms, 0);
353 FreeStmt(&append->common);
359 LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn)
363 if (!str || istreq(str, "any") || istreq(str, "nosymbol")) {
364 *sym_rtrn = XKB_KEY_NoSymbol;
368 if (istreq(str, "none") || istreq(str, "voidsymbol")) {
369 *sym_rtrn = XKB_KEY_VoidSymbol;
373 sym = xkb_keysym_from_name(str);
374 if (sym != XKB_KEY_NoSymbol) {
383 FreeInclude(IncludeStmt *incl);
386 IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
388 IncludeStmt *incl, *first;
389 char *file, *map, *stmt, *tmp, *extra_data;
395 stmt = strdup_safe(str);
398 if (!XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
402 first = incl = malloc(sizeof(*first));
404 incl->next_incl = malloc(sizeof(*first));
405 incl = incl->next_incl;
410 "Allocation failure in IncludeCreate; "
411 "Using only part of the include\n");
415 incl->common.type = STMT_INCLUDE;
416 incl->common.next = NULL;
421 incl->modifier = extra_data;
422 incl->next_incl = NULL;
425 merge = MERGE_AUGMENT;
427 merge = MERGE_OVERRIDE;
438 log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt);
445 CheckDefaultMap(struct xkb_context *ctx, XkbFile *maps, const char *fileName)
447 XkbFile *dflt = NULL, *tmp;
449 for (tmp = maps; tmp; tmp = (XkbFile *) tmp->common.next) {
450 if (!(tmp->flags & XkbLC_Default))
458 "Multiple default components in %s; "
459 "Using %s, ignoring %s\n",
460 (fileName ? fileName : "(unknown)"),
461 (dflt->name ? dflt->name : "(first)"),
462 (tmp->name ? tmp->name : "(subsequent)"));
464 tmp->flags &= (~XkbLC_Default);
469 * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
472 static const unsigned char componentSpecLegal[] = {
473 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
474 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
480 EnsureSafeMapName(char *name)
485 while (*name != '\0') {
486 if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0)
493 CreateXKBFile(struct xkb_context *ctx, enum xkb_file_type type, char *name,
494 ParseCommon *defs, unsigned flags)
498 file = calloc(1, sizeof(*file));
502 EnsureSafeMapName(name);
503 file->file_type = type;
504 file->topName = strdup_safe(name);
507 file->id = xkb_context_take_file_id(ctx);
513 FreeExpr(ExprDef *expr)
521 case EXPR_ACTION_LIST:
523 case EXPR_UNARY_PLUS:
526 FreeStmt(&expr->value.child->common);
534 FreeStmt(&expr->value.binary.left->common);
535 FreeStmt(&expr->value.binary.right->common);
538 case EXPR_ACTION_DECL:
539 FreeStmt(&expr->value.action.args->common);
543 FreeStmt(&expr->value.array.entry->common);
546 case EXPR_KEYSYM_LIST:
547 darray_foreach(sym, expr->value.list.syms)
549 darray_free(expr->value.list.syms);
550 darray_free(expr->value.list.symsMapIndex);
551 darray_free(expr->value.list.symsNumEntries);
560 FreeInclude(IncludeStmt *incl)
566 next = incl->next_incl;
570 free(incl->modifier);
579 FreeStmt(ParseCommon *stmt)
589 switch (stmt->type) {
591 FreeInclude((IncludeStmt *) stmt);
592 /* stmt is already free'd here. */
599 FreeStmt(&u.var->name->common);
600 FreeStmt(&u.var->value->common);
603 FreeStmt(&u.keyType->body->common);
607 FreeStmt(&u.interp->match->common);
608 FreeStmt(&u.interp->def->common);
611 FreeStmt(&u.vmod->value->common);
614 FreeStmt(&u.syms->symbols->common);
617 FreeStmt(&u.modMask->keys->common);
619 case STMT_GROUP_COMPAT:
620 FreeStmt(&u.groupCompat->def->common);
622 case STMT_INDICATOR_MAP:
623 FreeStmt(&u.ledMap->body->common);
625 case STMT_INDICATOR_NAME:
626 FreeStmt(&u.ledName->name->common);
638 FreeXKBFile(XkbFile *file)
644 next = (XkbFile *) file->common.next;
646 switch (file->file_type) {
647 case FILE_TYPE_KEYMAP:
648 FreeXKBFile((XkbFile *) file->defs);
651 case FILE_TYPE_TYPES:
652 case FILE_TYPE_COMPAT:
653 case FILE_TYPE_SYMBOLS:
654 case FILE_TYPE_KEYCODES:
655 case FILE_TYPE_GEOMETRY:
656 FreeStmt(file->defs);
670 const char *stmt_type_strings[_STMT_NUM_VALUES] = {
671 [STMT_UNKNOWN] = "unknown statement",
672 [STMT_INCLUDE] = "include statement",
673 [STMT_KEYCODE] = "key name definition",
674 [STMT_ALIAS] = "key alias definition",
675 [STMT_EXPR] = "expression",
676 [STMT_VAR] = "variable definition",
677 [STMT_TYPE] = "key type definition",
678 [STMT_INTERP] = "symbol interpretation definition",
679 [STMT_VMOD] = "virtual modifiers definition",
680 [STMT_SYMBOLS] = "key symbols definition",
681 [STMT_MODMAP] = "modifier map declaration",
682 [STMT_GROUP_COMPAT] = "group declaration",
683 [STMT_INDICATOR_MAP] = "indicator map declaration",
684 [STMT_INDICATOR_NAME] = "indicator name declaration",
688 StmtTypeToString(enum stmt_type type)
690 if (type >= _STMT_NUM_VALUES)
692 return stmt_type_strings[type];