1 /************************************************************
2 * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3 *
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.
15 *
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.
24 *
25 ********************************************************/
26
27 /*
28 * Copyright © 2012 Intel Corporation
29 * Copyright © 2012 Ran Benita <ran234@gmail.com>
30 *
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:
37 *
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
40 * Software.
41 *
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.
49 *
50 * Author: Daniel Stone <daniel@fooishbar.org>
51 * Ran Benita <ran234@gmail.com>
52 */
53
54 #include "config.h"
55
56 #include "xkbcomp-priv.h"
57 #include "ast-build.h"
58 #include "include.h"
59
60 static ExprDef *
ExprCreate(enum expr_op_type op,enum expr_value_type type,size_t size)61 ExprCreate(enum expr_op_type op, enum expr_value_type type, size_t size)
62 {
63 ExprDef *expr = malloc(size);
64 if (!expr)
65 return NULL;
66
67 expr->common.type = STMT_EXPR;
68 expr->common.next = NULL;
69 expr->expr.op = op;
70 expr->expr.value_type = type;
71
72 return expr;
73 }
74
75 ExprDef *
ExprCreateString(xkb_atom_t str)76 ExprCreateString(xkb_atom_t str)
77 {
78 ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING, sizeof(ExprString));
79 if (!expr)
80 return NULL;
81 expr->string.str = str;
82 return expr;
83 }
84
85 ExprDef *
ExprCreateInteger(int ival)86 ExprCreateInteger(int ival)
87 {
88 ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT, sizeof(ExprInteger));
89 if (!expr)
90 return NULL;
91 expr->integer.ival = ival;
92 return expr;
93 }
94
95 ExprDef *
ExprCreateFloat(void)96 ExprCreateFloat(void)
97 {
98 ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_FLOAT, sizeof(ExprFloat));
99 if (!expr)
100 return NULL;
101 return expr;
102 }
103
104 ExprDef *
ExprCreateBoolean(bool set)105 ExprCreateBoolean(bool set)
106 {
107 ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN, sizeof(ExprBoolean));
108 if (!expr)
109 return NULL;
110 expr->boolean.set = set;
111 return expr;
112 }
113
114 ExprDef *
ExprCreateKeyName(xkb_atom_t key_name)115 ExprCreateKeyName(xkb_atom_t key_name)
116 {
117 ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME, sizeof(ExprKeyName));
118 if (!expr)
119 return NULL;
120 expr->key_name.key_name = key_name;
121 return expr;
122 }
123
124 ExprDef *
ExprCreateIdent(xkb_atom_t ident)125 ExprCreateIdent(xkb_atom_t ident)
126 {
127 ExprDef *expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN, sizeof(ExprIdent));
128 if (!expr)
129 return NULL;
130 expr->ident.ident = ident;
131 return expr;
132 }
133
134 ExprDef *
ExprCreateUnary(enum expr_op_type op,enum expr_value_type type,ExprDef * child)135 ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
136 ExprDef *child)
137 {
138 ExprDef *expr = ExprCreate(op, type, sizeof(ExprUnary));
139 if (!expr)
140 return NULL;
141 expr->unary.child = child;
142 return expr;
143 }
144
145 ExprDef *
ExprCreateBinary(enum expr_op_type op,ExprDef * left,ExprDef * right)146 ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
147 {
148 ExprDef *expr = ExprCreate(op, EXPR_TYPE_UNKNOWN, sizeof(ExprBinary));
149 if (!expr)
150 return NULL;
151
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;
159
160 return expr;
161 }
162
163 ExprDef *
ExprCreateFieldRef(xkb_atom_t element,xkb_atom_t field)164 ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field)
165 {
166 ExprDef *expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN, sizeof(ExprFieldRef));
167 if (!expr)
168 return NULL;
169 expr->field_ref.element = element;
170 expr->field_ref.field = field;
171 return expr;
172 }
173
174 ExprDef *
ExprCreateArrayRef(xkb_atom_t element,xkb_atom_t field,ExprDef * entry)175 ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry)
176 {
177 ExprDef *expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN, sizeof(ExprArrayRef));
178 if (!expr)
179 return NULL;
180 expr->array_ref.element = element;
181 expr->array_ref.field = field;
182 expr->array_ref.entry = entry;
183 return expr;
184 }
185
186 ExprDef *
ExprCreateAction(xkb_atom_t name,ExprDef * args)187 ExprCreateAction(xkb_atom_t name, ExprDef *args)
188 {
189 ExprDef *expr = ExprCreate(EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN, sizeof(ExprAction));
190 if (!expr)
191 return NULL;
192 expr->action.name = name;
193 expr->action.args = args;
194 return expr;
195 }
196
197 ExprDef *
ExprCreateActionList(ExprDef * actions)198 ExprCreateActionList(ExprDef *actions)
199 {
200 ExprDef *expr = ExprCreate(EXPR_ACTION_LIST, EXPR_TYPE_ACTIONS, sizeof(ExprActionList));
201 if (!expr)
202 return NULL;
203 expr->actions.actions = actions;
204 return expr;
205 }
206
207 ExprDef *
ExprCreateKeysymList(xkb_keysym_t sym)208 ExprCreateKeysymList(xkb_keysym_t sym)
209 {
210 ExprDef *expr = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS, sizeof(ExprKeysymList));
211 if (!expr)
212 return NULL;
213
214 darray_init(expr->keysym_list.syms);
215 darray_init(expr->keysym_list.symsMapIndex);
216 darray_init(expr->keysym_list.symsNumEntries);
217
218 darray_append(expr->keysym_list.syms, sym);
219 darray_append(expr->keysym_list.symsMapIndex, 0);
220 darray_append(expr->keysym_list.symsNumEntries, 1);
221
222 return expr;
223 }
224
225 ExprDef *
ExprCreateMultiKeysymList(ExprDef * expr)226 ExprCreateMultiKeysymList(ExprDef *expr)
227 {
228 unsigned nLevels = darray_size(expr->keysym_list.symsMapIndex);
229
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;
234
235 return expr;
236 }
237
238 ExprDef *
ExprAppendKeysymList(ExprDef * expr,xkb_keysym_t sym)239 ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym)
240 {
241 unsigned nSyms = darray_size(expr->keysym_list.syms);
242
243 darray_append(expr->keysym_list.symsMapIndex, nSyms);
244 darray_append(expr->keysym_list.symsNumEntries, 1);
245 darray_append(expr->keysym_list.syms, sym);
246
247 return expr;
248 }
249
250 ExprDef *
ExprAppendMultiKeysymList(ExprDef * expr,ExprDef * append)251 ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append)
252 {
253 unsigned nSyms = darray_size(expr->keysym_list.syms);
254 unsigned numEntries = darray_size(append->keysym_list.syms);
255
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);
259
260 FreeStmt((ParseCommon *) append);
261
262 return expr;
263 }
264
265 KeycodeDef *
KeycodeCreate(xkb_atom_t name,int64_t value)266 KeycodeCreate(xkb_atom_t name, int64_t value)
267 {
268 KeycodeDef *def = malloc(sizeof(*def));
269 if (!def)
270 return NULL;
271
272 def->common.type = STMT_KEYCODE;
273 def->common.next = NULL;
274 def->name = name;
275 def->value = value;
276
277 return def;
278 }
279
280 KeyAliasDef *
KeyAliasCreate(xkb_atom_t alias,xkb_atom_t real)281 KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real)
282 {
283 KeyAliasDef *def = malloc(sizeof(*def));
284 if (!def)
285 return NULL;
286
287 def->common.type = STMT_ALIAS;
288 def->common.next = NULL;
289 def->alias = alias;
290 def->real = real;
291
292 return def;
293 }
294
295 VModDef *
VModCreate(xkb_atom_t name,ExprDef * value)296 VModCreate(xkb_atom_t name, ExprDef *value)
297 {
298 VModDef *def = malloc(sizeof(*def));
299 if (!def)
300 return NULL;
301
302 def->common.type = STMT_VMOD;
303 def->common.next = NULL;
304 def->name = name;
305 def->value = value;
306
307 return def;
308 }
309
310 VarDef *
VarCreate(ExprDef * name,ExprDef * value)311 VarCreate(ExprDef *name, ExprDef *value)
312 {
313 VarDef *def = malloc(sizeof(*def));
314 if (!def)
315 return NULL;
316
317 def->common.type = STMT_VAR;
318 def->common.next = NULL;
319 def->name = name;
320 def->value = value;
321
322 return def;
323 }
324
325 VarDef *
BoolVarCreate(xkb_atom_t ident,bool set)326 BoolVarCreate(xkb_atom_t ident, bool set)
327 {
328 ExprDef *name, *value;
329 VarDef *def;
330 if (!(name = ExprCreateIdent(ident))) {
331 return NULL;
332 }
333 if (!(value = ExprCreateBoolean(set))) {
334 FreeStmt((ParseCommon *) name);
335 return NULL;
336 }
337 if (!(def = VarCreate(name, value))) {
338 FreeStmt((ParseCommon *) name);
339 FreeStmt((ParseCommon *) value);
340 return NULL;
341 }
342 return def;
343 }
344
345 InterpDef *
InterpCreate(xkb_keysym_t sym,ExprDef * match)346 InterpCreate(xkb_keysym_t sym, ExprDef *match)
347 {
348 InterpDef *def = malloc(sizeof(*def));
349 if (!def)
350 return NULL;
351
352 def->common.type = STMT_INTERP;
353 def->common.next = NULL;
354 def->sym = sym;
355 def->match = match;
356 def->def = NULL;
357
358 return def;
359 }
360
361 KeyTypeDef *
KeyTypeCreate(xkb_atom_t name,VarDef * body)362 KeyTypeCreate(xkb_atom_t name, VarDef *body)
363 {
364 KeyTypeDef *def = malloc(sizeof(*def));
365 if (!def)
366 return NULL;
367
368 def->common.type = STMT_TYPE;
369 def->common.next = NULL;
370 def->merge = MERGE_DEFAULT;
371 def->name = name;
372 def->body = body;
373
374 return def;
375 }
376
377 SymbolsDef *
SymbolsCreate(xkb_atom_t keyName,VarDef * symbols)378 SymbolsCreate(xkb_atom_t keyName, VarDef *symbols)
379 {
380 SymbolsDef *def = malloc(sizeof(*def));
381 if (!def)
382 return NULL;
383
384 def->common.type = STMT_SYMBOLS;
385 def->common.next = NULL;
386 def->merge = MERGE_DEFAULT;
387 def->keyName = keyName;
388 def->symbols = symbols;
389
390 return def;
391 }
392
393 GroupCompatDef *
GroupCompatCreate(unsigned group,ExprDef * val)394 GroupCompatCreate(unsigned group, ExprDef *val)
395 {
396 GroupCompatDef *def = malloc(sizeof(*def));
397 if (!def)
398 return NULL;
399
400 def->common.type = STMT_GROUP_COMPAT;
401 def->common.next = NULL;
402 def->merge = MERGE_DEFAULT;
403 def->group = group;
404 def->def = val;
405
406 return def;
407 }
408
409 ModMapDef *
ModMapCreate(xkb_atom_t modifier,ExprDef * keys)410 ModMapCreate(xkb_atom_t modifier, ExprDef *keys)
411 {
412 ModMapDef *def = malloc(sizeof(*def));
413 if (!def)
414 return NULL;
415
416 def->common.type = STMT_MODMAP;
417 def->common.next = NULL;
418 def->merge = MERGE_DEFAULT;
419 def->modifier = modifier;
420 def->keys = keys;
421
422 return def;
423 }
424
425 LedMapDef *
LedMapCreate(xkb_atom_t name,VarDef * body)426 LedMapCreate(xkb_atom_t name, VarDef *body)
427 {
428 LedMapDef *def = malloc(sizeof(*def));
429 if (!def)
430 return NULL;
431
432 def->common.type = STMT_LED_MAP;
433 def->common.next = NULL;
434 def->merge = MERGE_DEFAULT;
435 def->name = name;
436 def->body = body;
437
438 return def;
439 }
440
441 LedNameDef *
LedNameCreate(unsigned ndx,ExprDef * name,bool virtual)442 LedNameCreate(unsigned ndx, ExprDef *name, bool virtual)
443 {
444 LedNameDef *def = malloc(sizeof(*def));
445 if (!def)
446 return NULL;
447
448 def->common.type = STMT_LED_NAME;
449 def->common.next = NULL;
450 def->merge = MERGE_DEFAULT;
451 def->ndx = ndx;
452 def->name = name;
453 def->virtual = virtual;
454
455 return def;
456 }
457
458 static void
459 FreeInclude(IncludeStmt *incl);
460
461 IncludeStmt *
IncludeCreate(struct xkb_context * ctx,char * str,enum merge_mode merge)462 IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
463 {
464 IncludeStmt *incl, *first;
465 char *stmt, *tmp;
466 char nextop;
467
468 incl = first = NULL;
469 tmp = str;
470 stmt = strdup_safe(str);
471 while (tmp && *tmp)
472 {
473 char *file = NULL, *map = NULL, *extra_data = NULL;
474
475 if (!ParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
476 goto err;
477
478 /*
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.
483 */
484 if (isempty(file)) {
485 free(file);
486 free(map);
487 free(extra_data);
488 continue;
489 }
490
491 if (first == NULL) {
492 first = incl = malloc(sizeof(*first));
493 } else {
494 incl->next_incl = malloc(sizeof(*first));
495 incl = incl->next_incl;
496 }
497
498 if (!incl) {
499 free(file);
500 free(map);
501 free(extra_data);
502 break;
503 }
504
505 incl->common.type = STMT_INCLUDE;
506 incl->common.next = NULL;
507 incl->merge = merge;
508 incl->stmt = NULL;
509 incl->file = file;
510 incl->map = map;
511 incl->modifier = extra_data;
512 incl->next_incl = NULL;
513
514 if (nextop == '|')
515 merge = MERGE_AUGMENT;
516 else
517 merge = MERGE_OVERRIDE;
518 }
519
520 if (first)
521 first->stmt = stmt;
522 else
523 free(stmt);
524
525 return first;
526
527 err:
528 log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt);
529 FreeInclude(first);
530 free(stmt);
531 return NULL;
532 }
533
534 XkbFile *
XkbFileCreate(enum xkb_file_type type,char * name,ParseCommon * defs,enum xkb_map_flags flags)535 XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs,
536 enum xkb_map_flags flags)
537 {
538 XkbFile *file;
539
540 file = calloc(1, sizeof(*file));
541 if (!file)
542 return NULL;
543
544 XkbEscapeMapName(name);
545 file->file_type = type;
546 file->name = name ? name : strdup("(unnamed)");
547 file->defs = defs;
548 file->flags = flags;
549
550 return file;
551 }
552
553 XkbFile *
XkbFileFromComponents(struct xkb_context * ctx,const struct xkb_component_names * kkctgs)554 XkbFileFromComponents(struct xkb_context *ctx,
555 const struct xkb_component_names *kkctgs)
556 {
557 char *const components[] = {
558 kkctgs->keycodes, kkctgs->types,
559 kkctgs->compat, kkctgs->symbols,
560 };
561 enum xkb_file_type type;
562 IncludeStmt *include = NULL;
563 XkbFile *file = NULL;
564 ParseCommon *defs = NULL, *defsLast = NULL;
565
566 for (type = FIRST_KEYMAP_FILE_TYPE; type <= LAST_KEYMAP_FILE_TYPE; type++) {
567 include = IncludeCreate(ctx, components[type], MERGE_DEFAULT);
568 if (!include)
569 goto err;
570
571 file = XkbFileCreate(type, NULL, (ParseCommon *) include, 0);
572 if (!file) {
573 FreeInclude(include);
574 goto err;
575 }
576
577 if (!defs)
578 defsLast = defs = &file->common;
579 else
580 defsLast = defsLast->next = &file->common;
581 }
582
583 file = XkbFileCreate(FILE_TYPE_KEYMAP, NULL, defs, 0);
584 if (!file)
585 goto err;
586
587 return file;
588
589 err:
590 FreeXkbFile((XkbFile *) defs);
591 return NULL;
592 }
593
594 static void
FreeExpr(ExprDef * expr)595 FreeExpr(ExprDef *expr)
596 {
597 if (!expr)
598 return;
599
600 switch (expr->expr.op) {
601 case EXPR_NEGATE:
602 case EXPR_UNARY_PLUS:
603 case EXPR_NOT:
604 case EXPR_INVERT:
605 FreeStmt((ParseCommon *) expr->unary.child);
606 break;
607
608 case EXPR_DIVIDE:
609 case EXPR_ADD:
610 case EXPR_SUBTRACT:
611 case EXPR_MULTIPLY:
612 case EXPR_ASSIGN:
613 FreeStmt((ParseCommon *) expr->binary.left);
614 FreeStmt((ParseCommon *) expr->binary.right);
615 break;
616
617 case EXPR_ACTION_DECL:
618 FreeStmt((ParseCommon *) expr->action.args);
619 break;
620
621 case EXPR_ACTION_LIST:
622 FreeStmt((ParseCommon *) expr->actions.actions);
623 break;
624
625 case EXPR_ARRAY_REF:
626 FreeStmt((ParseCommon *) expr->array_ref.entry);
627 break;
628
629 case EXPR_KEYSYM_LIST:
630 darray_free(expr->keysym_list.syms);
631 darray_free(expr->keysym_list.symsMapIndex);
632 darray_free(expr->keysym_list.symsNumEntries);
633 break;
634
635 default:
636 break;
637 }
638 }
639
640 static void
FreeInclude(IncludeStmt * incl)641 FreeInclude(IncludeStmt *incl)
642 {
643 IncludeStmt *next;
644
645 while (incl)
646 {
647 next = incl->next_incl;
648
649 free(incl->file);
650 free(incl->map);
651 free(incl->modifier);
652 free(incl->stmt);
653
654 free(incl);
655 incl = next;
656 }
657 }
658
659 void
FreeStmt(ParseCommon * stmt)660 FreeStmt(ParseCommon *stmt)
661 {
662 ParseCommon *next;
663
664 while (stmt)
665 {
666 next = stmt->next;
667
668 switch (stmt->type) {
669 case STMT_INCLUDE:
670 FreeInclude((IncludeStmt *) stmt);
671 /* stmt is already free'd here. */
672 stmt = NULL;
673 break;
674 case STMT_EXPR:
675 FreeExpr((ExprDef *) stmt);
676 break;
677 case STMT_VAR:
678 FreeStmt((ParseCommon *) ((VarDef *) stmt)->name);
679 FreeStmt((ParseCommon *) ((VarDef *) stmt)->value);
680 break;
681 case STMT_TYPE:
682 FreeStmt((ParseCommon *) ((KeyTypeDef *) stmt)->body);
683 break;
684 case STMT_INTERP:
685 FreeStmt((ParseCommon *) ((InterpDef *) stmt)->match);
686 FreeStmt((ParseCommon *) ((InterpDef *) stmt)->def);
687 break;
688 case STMT_VMOD:
689 FreeStmt((ParseCommon *) ((VModDef *) stmt)->value);
690 break;
691 case STMT_SYMBOLS:
692 FreeStmt((ParseCommon *) ((SymbolsDef *) stmt)->symbols);
693 break;
694 case STMT_MODMAP:
695 FreeStmt((ParseCommon *) ((ModMapDef *) stmt)->keys);
696 break;
697 case STMT_GROUP_COMPAT:
698 FreeStmt((ParseCommon *) ((GroupCompatDef *) stmt)->def);
699 break;
700 case STMT_LED_MAP:
701 FreeStmt((ParseCommon *) ((LedMapDef *) stmt)->body);
702 break;
703 case STMT_LED_NAME:
704 FreeStmt((ParseCommon *) ((LedNameDef *) stmt)->name);
705 break;
706 default:
707 break;
708 }
709
710 free(stmt);
711 stmt = next;
712 }
713 }
714
715 void
FreeXkbFile(XkbFile * file)716 FreeXkbFile(XkbFile *file)
717 {
718 XkbFile *next;
719
720 while (file)
721 {
722 next = (XkbFile *) file->common.next;
723
724 switch (file->file_type) {
725 case FILE_TYPE_KEYMAP:
726 FreeXkbFile((XkbFile *) file->defs);
727 break;
728
729 case FILE_TYPE_TYPES:
730 case FILE_TYPE_COMPAT:
731 case FILE_TYPE_SYMBOLS:
732 case FILE_TYPE_KEYCODES:
733 case FILE_TYPE_GEOMETRY:
734 FreeStmt(file->defs);
735 break;
736
737 default:
738 break;
739 }
740
741 free(file->name);
742 free(file);
743 file = next;
744 }
745 }
746
747 static const char *xkb_file_type_strings[_FILE_TYPE_NUM_ENTRIES] = {
748 [FILE_TYPE_KEYCODES] = "xkb_keycodes",
749 [FILE_TYPE_TYPES] = "xkb_types",
750 [FILE_TYPE_COMPAT] = "xkb_compatibility",
751 [FILE_TYPE_SYMBOLS] = "xkb_symbols",
752 [FILE_TYPE_GEOMETRY] = "xkb_geometry",
753 [FILE_TYPE_KEYMAP] = "xkb_keymap",
754 [FILE_TYPE_RULES] = "rules",
755 };
756
757 const char *
xkb_file_type_to_string(enum xkb_file_type type)758 xkb_file_type_to_string(enum xkb_file_type type)
759 {
760 if (type >= _FILE_TYPE_NUM_ENTRIES)
761 return "unknown";
762 return xkb_file_type_strings[type];
763 }
764
765 static const char *stmt_type_strings[_STMT_NUM_VALUES] = {
766 [STMT_UNKNOWN] = "unknown statement",
767 [STMT_INCLUDE] = "include statement",
768 [STMT_KEYCODE] = "key name definition",
769 [STMT_ALIAS] = "key alias definition",
770 [STMT_EXPR] = "expression",
771 [STMT_VAR] = "variable definition",
772 [STMT_TYPE] = "key type definition",
773 [STMT_INTERP] = "symbol interpretation definition",
774 [STMT_VMOD] = "virtual modifiers definition",
775 [STMT_SYMBOLS] = "key symbols definition",
776 [STMT_MODMAP] = "modifier map declaration",
777 [STMT_GROUP_COMPAT] = "group declaration",
778 [STMT_LED_MAP] = "indicator map declaration",
779 [STMT_LED_NAME] = "indicator name declaration",
780 };
781
782 const char *
stmt_type_to_string(enum stmt_type type)783 stmt_type_to_string(enum stmt_type type)
784 {
785 if (type >= _STMT_NUM_VALUES)
786 return NULL;
787 return stmt_type_strings[type];
788 }
789
790 static const char *expr_op_type_strings[_EXPR_NUM_VALUES] = {
791 [EXPR_VALUE] = "literal",
792 [EXPR_IDENT] = "identifier",
793 [EXPR_ACTION_DECL] = "action declaration",
794 [EXPR_FIELD_REF] = "field reference",
795 [EXPR_ARRAY_REF] = "array reference",
796 [EXPR_KEYSYM_LIST] = "list of keysyms",
797 [EXPR_ACTION_LIST] = "list of actions",
798 [EXPR_ADD] = "addition",
799 [EXPR_SUBTRACT] = "subtraction",
800 [EXPR_MULTIPLY] = "multiplication",
801 [EXPR_DIVIDE] = "division",
802 [EXPR_ASSIGN] = "assignment",
803 [EXPR_NOT] = "logical negation",
804 [EXPR_NEGATE] = "arithmetic negation",
805 [EXPR_INVERT] = "bitwise inversion",
806 [EXPR_UNARY_PLUS] = "unary plus",
807 };
808
809 const char *
expr_op_type_to_string(enum expr_op_type type)810 expr_op_type_to_string(enum expr_op_type type)
811 {
812 if (type >= _EXPR_NUM_VALUES)
813 return NULL;
814 return expr_op_type_strings[type];
815 }
816
817 static const char *expr_value_type_strings[_EXPR_TYPE_NUM_VALUES] = {
818 [EXPR_TYPE_UNKNOWN] = "unknown",
819 [EXPR_TYPE_BOOLEAN] = "boolean",
820 [EXPR_TYPE_INT] = "int",
821 [EXPR_TYPE_FLOAT] = "float",
822 [EXPR_TYPE_STRING] = "string",
823 [EXPR_TYPE_ACTION] = "action",
824 [EXPR_TYPE_ACTIONS] = "actions",
825 [EXPR_TYPE_KEYNAME] = "keyname",
826 [EXPR_TYPE_SYMBOLS] = "symbols",
827 };
828
829 const char *
expr_value_type_to_string(enum expr_value_type type)830 expr_value_type_to_string(enum expr_value_type type)
831 {
832 if (type >= _EXPR_TYPE_NUM_VALUES)
833 return NULL;
834 return expr_value_type_strings[type];
835 }
836