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);
120 def->name[XkbKeyNameLength] = '\0';
126 KeyAliasCreate(char alias[XkbKeyNameLength], char real[XkbKeyNameLength])
130 def = malloc_or_die(sizeof(*def));
132 def->common.type = STMT_ALIAS;
133 def->common.next = NULL;
134 strncpy(def->alias, alias, XkbKeyNameLength);
135 def->alias[XkbKeyNameLength] = '\0';
136 strncpy(def->real, real, XkbKeyNameLength);
137 def->real[XkbKeyNameLength] = '\0';
142 VModCreate(xkb_atom_t name, ExprDef * value)
146 def = malloc_or_die(sizeof(*def));
148 def->common.type = STMT_VMOD;
149 def->common.next = NULL;
156 VarCreate(ExprDef * name, ExprDef * value)
159 def = malloc_or_die(sizeof(*def));
161 def->common.type = STMT_VAR;
162 def->common.next = NULL;
169 BoolVarCreate(xkb_atom_t nameToken, unsigned set)
171 ExprDef *name, *value;
173 name = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
174 name->value.str = nameToken;
175 value = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN);
176 value->value.uval = set;
177 return VarCreate(name, value);
181 InterpCreate(char *sym, ExprDef * match)
185 def = malloc_or_die(sizeof(*def));
187 def->common.type = STMT_INTERP;
188 def->common.next = NULL;
195 KeyTypeCreate(xkb_atom_t name, VarDef * body)
199 def = malloc_or_die(sizeof(*def));
201 def->common.type = STMT_TYPE;
202 def->common.next = NULL;
203 def->merge = MERGE_DEFAULT;
210 SymbolsCreate(char keyName[XkbKeyNameLength], ExprDef *symbols)
214 def = malloc_or_die(sizeof(*def));
216 def->common.type = STMT_SYMBOLS;
217 def->common.next = NULL;
218 def->merge = MERGE_DEFAULT;
219 strncpy(def->keyName, keyName, XkbKeyNameLength);
220 def->symbols = symbols;
225 GroupCompatCreate(int group, ExprDef * val)
229 def = malloc_or_die(sizeof(*def));
231 def->common.type = STMT_GROUP_COMPAT;
232 def->common.next = NULL;
233 def->merge = MERGE_DEFAULT;
240 ModMapCreate(uint32_t modifier, ExprDef * keys)
244 def = malloc_or_die(sizeof(*def));
246 def->common.type = STMT_MODMAP;
247 def->common.next = NULL;
248 def->merge = MERGE_DEFAULT;
249 def->modifier = modifier;
255 IndicatorMapCreate(xkb_atom_t name, VarDef * body)
257 IndicatorMapDef *def;
259 def = malloc_or_die(sizeof(*def));
261 def->common.type = STMT_INDICATOR_MAP;
262 def->common.next = NULL;
263 def->merge = MERGE_DEFAULT;
270 IndicatorNameCreate(int ndx, ExprDef * name, bool virtual)
272 IndicatorNameDef *def;
274 def = malloc_or_die(sizeof(*def));
276 def->common.type = STMT_INDICATOR_NAME;
277 def->common.next = NULL;
278 def->merge = MERGE_DEFAULT;
281 def->virtual = virtual;
286 ActionCreate(xkb_atom_t name, ExprDef * args)
290 act = malloc_or_die(sizeof(*act));
292 act->common.type = STMT_EXPR;
293 act->common.next = NULL;
294 act->op = EXPR_ACTION_DECL;
295 act->value.action.name = name;
296 act->value.action.args = args;
301 CreateKeysymList(char *sym)
305 def = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
307 darray_init(def->value.list.syms);
308 darray_init(def->value.list.symsMapIndex);
309 darray_init(def->value.list.symsNumEntries);
311 darray_append(def->value.list.syms, sym);
312 darray_append(def->value.list.symsMapIndex, 0);
313 darray_append(def->value.list.symsNumEntries, 1);
319 CreateMultiKeysymList(ExprDef *list)
321 size_t nLevels = darray_size(list->value.list.symsMapIndex);
323 darray_resize(list->value.list.symsMapIndex, 1);
324 darray_resize(list->value.list.symsNumEntries, 1);
325 darray_item(list->value.list.symsMapIndex, 0) = 0;
326 darray_item(list->value.list.symsNumEntries, 0) = nLevels;
332 AppendKeysymList(ExprDef * list, char *sym)
334 size_t nSyms = darray_size(list->value.list.syms);
336 darray_append(list->value.list.symsMapIndex, nSyms);
337 darray_append(list->value.list.symsNumEntries, 1);
338 darray_append(list->value.list.syms, sym);
344 AppendMultiKeysymList(ExprDef * list, ExprDef * append)
346 size_t nSyms = darray_size(list->value.list.syms);
347 size_t numEntries = darray_size(append->value.list.syms);
349 darray_append(list->value.list.symsMapIndex, nSyms);
350 darray_append(list->value.list.symsNumEntries, numEntries);
351 darray_append_items(list->value.list.syms,
352 darray_mem(append->value.list.syms, 0),
355 darray_resize(append->value.list.syms, 0);
356 FreeStmt(&append->common);
362 LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn)
366 if (!str || istreq(str, "any") || istreq(str, "nosymbol")) {
367 *sym_rtrn = XKB_KEY_NoSymbol;
371 if (istreq(str, "none") || istreq(str, "voidsymbol")) {
372 *sym_rtrn = XKB_KEY_VoidSymbol;
376 sym = xkb_keysym_from_name(str);
377 if (sym != XKB_KEY_NoSymbol) {
386 FreeInclude(IncludeStmt *incl);
389 IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
391 IncludeStmt *incl, *first;
392 char *file, *map, *stmt, *tmp, *extra_data;
398 stmt = strdup_safe(str);
401 if (!XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
405 first = incl = malloc(sizeof(*first));
407 incl->next_incl = malloc(sizeof(*first));
408 incl = incl->next_incl;
413 "Allocation failure in IncludeCreate; "
414 "Using only part of the include\n");
418 incl->common.type = STMT_INCLUDE;
419 incl->common.next = NULL;
424 incl->modifier = extra_data;
426 incl->next_incl = NULL;
429 merge = MERGE_AUGMENT;
431 merge = MERGE_OVERRIDE;
442 log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt);
449 CheckDefaultMap(struct xkb_context *ctx, XkbFile *maps, const char *fileName)
451 XkbFile *dflt = NULL, *tmp;
453 for (tmp = maps; tmp; tmp = (XkbFile *) tmp->common.next) {
454 if (!(tmp->flags & XkbLC_Default))
462 "Multiple default components in %s; "
463 "Using %s, ignoring %s\n",
464 (fileName ? fileName : "(unknown)"),
465 (dflt->name ? dflt->name : "(first)"),
466 (tmp->name ? tmp->name : "(subsequent)"));
468 tmp->flags &= (~XkbLC_Default);
473 * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
476 static const unsigned char componentSpecLegal[] = {
477 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
478 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
479 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
484 EnsureSafeMapName(char *name)
489 while (*name != '\0') {
490 if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0)
497 CreateXKBFile(struct xkb_context *ctx, enum xkb_file_type type, char *name,
498 ParseCommon *defs, unsigned flags)
502 file = calloc(1, sizeof(*file));
506 EnsureSafeMapName(name);
507 file->file_type = type;
508 file->topName = strdup_safe(name);
511 file->id = xkb_context_take_file_id(ctx);
517 FreeExpr(ExprDef *expr)
525 case EXPR_ACTION_LIST:
527 case EXPR_UNARY_PLUS:
530 FreeStmt(&expr->value.child->common);
538 FreeStmt(&expr->value.binary.left->common);
539 FreeStmt(&expr->value.binary.right->common);
542 case EXPR_ACTION_DECL:
543 FreeStmt(&expr->value.action.args->common);
547 FreeStmt(&expr->value.array.entry->common);
550 case EXPR_KEYSYM_LIST:
551 darray_foreach(sym, expr->value.list.syms)
553 darray_free(expr->value.list.syms);
554 darray_free(expr->value.list.symsMapIndex);
555 darray_free(expr->value.list.symsNumEntries);
564 FreeInclude(IncludeStmt *incl)
570 next = incl->next_incl;
574 free(incl->modifier);
584 FreeStmt(ParseCommon *stmt)
594 switch (stmt->type) {
596 FreeInclude((IncludeStmt *) stmt);
597 /* stmt is already free'd here. */
604 FreeStmt(&u.var->name->common);
605 FreeStmt(&u.var->value->common);
608 FreeStmt(&u.keyType->body->common);
612 FreeStmt(&u.interp->match->common);
613 FreeStmt(&u.interp->def->common);
616 FreeStmt(&u.vmod->value->common);
619 FreeStmt(&u.syms->symbols->common);
622 FreeStmt(&u.modMask->keys->common);
624 case STMT_GROUP_COMPAT:
625 FreeStmt(&u.groupCompat->def->common);
627 case STMT_INDICATOR_MAP:
628 FreeStmt(&u.ledMap->body->common);
630 case STMT_INDICATOR_NAME:
631 FreeStmt(&u.ledName->name->common);
643 FreeXKBFile(XkbFile *file)
649 next = (XkbFile *) file->common.next;
651 switch (file->file_type) {
652 case FILE_TYPE_KEYMAP:
653 FreeXKBFile((XkbFile *) file->defs);
656 case FILE_TYPE_TYPES:
657 case FILE_TYPE_COMPAT:
658 case FILE_TYPE_SYMBOLS:
659 case FILE_TYPE_KEYCODES:
660 case FILE_TYPE_GEOMETRY:
661 FreeStmt(file->defs);