Allocate xkb_component_names on stack
[platform/upstream/libxkbcommon.git] / src / xkbcomp / parseutils.c
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 #include "parseutils.h"
28 #include "path.h"
29
30 ATTR_MALLOC static void *
31 malloc_or_die(size_t size)
32 {
33     void *p = malloc(size);
34     if (!p) {
35         fprintf(stderr, "Out of memory\n");
36         exit(1);
37     }
38     return p;
39 }
40
41 ParseCommon *
42 AppendStmt(ParseCommon * to, ParseCommon * append)
43 {
44     ParseCommon *start = to;
45
46     if (append == NULL)
47         return to;
48     while ((to != NULL) && (to->next != NULL))
49     {
50         to = to->next;
51     }
52     if (to) {
53         to->next = append;
54         return start;
55     }
56     return append;
57 }
58
59 ExprDef *
60 ExprCreate(enum expr_op_type op, enum expr_value_type type)
61 {
62     ExprDef *expr;
63
64     expr = malloc_or_die(sizeof(*expr));
65
66     expr->common.type = STMT_EXPR;
67     expr->common.next = NULL;
68     expr->op = op;
69     expr->value_type = type;
70     return expr;
71 }
72
73 ExprDef *
74 ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
75                 ExprDef *child)
76 {
77     ExprDef *expr;
78     expr = malloc_or_die(sizeof(*expr));
79
80     expr->common.type = STMT_EXPR;
81     expr->common.next = NULL;
82     expr->op = op;
83     expr->value_type = type;
84     expr->value.child = child;
85     return expr;
86 }
87
88 ExprDef *
89 ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
90 {
91     ExprDef *expr;
92
93     expr = malloc_or_die(sizeof(*expr));
94
95     expr->common.type = STMT_EXPR;
96     expr->common.next = NULL;
97     expr->op = op;
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;
103     else
104         expr->value_type = EXPR_TYPE_UNKNOWN;
105     expr->value.binary.left = left;
106     expr->value.binary.right = right;
107     return expr;
108 }
109
110 KeycodeDef *
111 KeycodeCreate(char keyName[XkbKeyNameLength], unsigned long value)
112 {
113     KeycodeDef *def;
114
115     def = malloc_or_die(sizeof(*def));
116
117     def->common.type = STMT_KEYCODE;
118     def->common.next = NULL;
119     strncpy(def->name, keyName, XkbKeyNameLength);
120     def->value = value;
121     return def;
122 }
123
124 KeyAliasDef *
125 KeyAliasCreate(char alias[XkbKeyNameLength], char real[XkbKeyNameLength])
126 {
127     KeyAliasDef *def;
128
129     def = malloc_or_die(sizeof(*def));
130
131     def->common.type = STMT_ALIAS;
132     def->common.next = NULL;
133     strncpy(def->alias, alias, XkbKeyNameLength);
134     strncpy(def->real, real, XkbKeyNameLength);
135     return def;
136 }
137
138 VModDef *
139 VModCreate(xkb_atom_t name, ExprDef * value)
140 {
141     VModDef *def;
142
143     def = malloc_or_die(sizeof(*def));
144
145     def->common.type = STMT_VMOD;
146     def->common.next = NULL;
147     def->name = name;
148     def->value = value;
149     return def;
150 }
151
152 VarDef *
153 VarCreate(ExprDef * name, ExprDef * value)
154 {
155     VarDef *def;
156     def = malloc_or_die(sizeof(*def));
157
158     def->common.type = STMT_VAR;
159     def->common.next = NULL;
160     def->name = name;
161     def->value = value;
162     return def;
163 }
164
165 VarDef *
166 BoolVarCreate(xkb_atom_t nameToken, unsigned set)
167 {
168     ExprDef *name, *value;
169
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);
175 }
176
177 InterpDef *
178 InterpCreate(char *sym, ExprDef * match)
179 {
180     InterpDef *def;
181
182     def = malloc_or_die(sizeof(*def));
183
184     def->common.type = STMT_INTERP;
185     def->common.next = NULL;
186     def->sym = sym;
187     def->match = match;
188     return def;
189 }
190
191 KeyTypeDef *
192 KeyTypeCreate(xkb_atom_t name, VarDef * body)
193 {
194     KeyTypeDef *def;
195
196     def = malloc_or_die(sizeof(*def));
197
198     def->common.type = STMT_TYPE;
199     def->common.next = NULL;
200     def->merge = MERGE_DEFAULT;
201     def->name = name;
202     def->body = body;
203     return def;
204 }
205
206 SymbolsDef *
207 SymbolsCreate(char keyName[XkbKeyNameLength], ExprDef *symbols)
208 {
209     SymbolsDef *def;
210
211     def = malloc_or_die(sizeof(*def));
212
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;
218     return def;
219 }
220
221 GroupCompatDef *
222 GroupCompatCreate(int group, ExprDef * val)
223 {
224     GroupCompatDef *def;
225
226     def = malloc_or_die(sizeof(*def));
227
228     def->common.type = STMT_GROUP_COMPAT;
229     def->common.next = NULL;
230     def->merge = MERGE_DEFAULT;
231     def->group = group;
232     def->def = val;
233     return def;
234 }
235
236 ModMapDef *
237 ModMapCreate(uint32_t modifier, ExprDef * keys)
238 {
239     ModMapDef *def;
240
241     def = malloc_or_die(sizeof(*def));
242
243     def->common.type = STMT_MODMAP;
244     def->common.next = NULL;
245     def->merge = MERGE_DEFAULT;
246     def->modifier = modifier;
247     def->keys = keys;
248     return def;
249 }
250
251 IndicatorMapDef *
252 IndicatorMapCreate(xkb_atom_t name, VarDef * body)
253 {
254     IndicatorMapDef *def;
255
256     def = malloc_or_die(sizeof(*def));
257
258     def->common.type = STMT_INDICATOR_MAP;
259     def->common.next = NULL;
260     def->merge = MERGE_DEFAULT;
261     def->name = name;
262     def->body = body;
263     return def;
264 }
265
266 IndicatorNameDef *
267 IndicatorNameCreate(int ndx, ExprDef * name, bool virtual)
268 {
269     IndicatorNameDef *def;
270
271     def = malloc_or_die(sizeof(*def));
272
273     def->common.type = STMT_INDICATOR_NAME;
274     def->common.next = NULL;
275     def->merge = MERGE_DEFAULT;
276     def->ndx = ndx;
277     def->name = name;
278     def->virtual = virtual;
279     return def;
280 }
281
282 ExprDef *
283 ActionCreate(xkb_atom_t name, ExprDef * args)
284 {
285     ExprDef *act;
286
287     act = malloc_or_die(sizeof(*act));
288
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;
294     return act;
295 }
296
297 ExprDef *
298 CreateKeysymList(char *sym)
299 {
300     ExprDef *def;
301
302     def = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
303
304     darray_init(def->value.list.syms);
305     darray_init(def->value.list.symsMapIndex);
306     darray_init(def->value.list.symsNumEntries);
307
308     darray_append(def->value.list.syms, sym);
309     darray_append(def->value.list.symsMapIndex, 0);
310     darray_append(def->value.list.symsNumEntries, 1);
311
312     return def;
313 }
314
315 ExprDef *
316 CreateMultiKeysymList(ExprDef *list)
317 {
318     size_t nLevels = darray_size(list->value.list.symsMapIndex);
319
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;
324
325     return list;
326 }
327
328 ExprDef *
329 AppendKeysymList(ExprDef * list, char *sym)
330 {
331     size_t nSyms = darray_size(list->value.list.syms);
332
333     darray_append(list->value.list.symsMapIndex, nSyms);
334     darray_append(list->value.list.symsNumEntries, 1);
335     darray_append(list->value.list.syms, sym);
336
337     return list;
338 }
339
340 ExprDef *
341 AppendMultiKeysymList(ExprDef * list, ExprDef * append)
342 {
343     size_t nSyms = darray_size(list->value.list.syms);
344     size_t numEntries = darray_size(append->value.list.syms);
345
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),
350                         numEntries);
351
352     darray_resize(append->value.list.syms, 0);
353     FreeStmt(&append->common);
354
355     return list;
356 }
357
358 bool
359 LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn)
360 {
361     xkb_keysym_t sym;
362
363     if (!str || istreq(str, "any") || istreq(str, "nosymbol")) {
364         *sym_rtrn = XKB_KEY_NoSymbol;
365         return 1;
366     }
367
368     if (istreq(str, "none") || istreq(str, "voidsymbol")) {
369         *sym_rtrn = XKB_KEY_VoidSymbol;
370         return 1;
371     }
372
373     sym = xkb_keysym_from_name(str);
374     if (sym != XKB_KEY_NoSymbol) {
375         *sym_rtrn = sym;
376         return 1;
377     }
378
379     return 0;
380 }
381
382 static void
383 FreeInclude(IncludeStmt *incl);
384
385 IncludeStmt *
386 IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
387 {
388     IncludeStmt *incl, *first;
389     char *file, *map, *stmt, *tmp, *extra_data;
390     char nextop;
391
392     incl = first = NULL;
393     file = map = NULL;
394     tmp = str;
395     stmt = strdup_safe(str);
396     while (tmp && *tmp)
397     {
398         if (!XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
399             goto err;
400
401         if (first == NULL) {
402             first = incl = malloc(sizeof(*first));
403         } else {
404             incl->next_incl = malloc(sizeof(*first));
405             incl = incl->next_incl;
406         }
407
408         if (!incl) {
409             log_wsgo(ctx,
410                      "Allocation failure in IncludeCreate; "
411                      "Using only part of the include\n");
412             break;
413         }
414
415         incl->common.type = STMT_INCLUDE;
416         incl->common.next = NULL;
417         incl->merge = merge;
418         incl->stmt = NULL;
419         incl->file = file;
420         incl->map = map;
421         incl->modifier = extra_data;
422         incl->next_incl = NULL;
423
424         if (nextop == '|')
425             merge = MERGE_AUGMENT;
426         else
427             merge = MERGE_OVERRIDE;
428     }
429
430     if (first)
431         first->stmt = stmt;
432     else
433         free(stmt);
434
435     return first;
436
437 err:
438     log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt);
439     FreeInclude(first);
440     free(stmt);
441     return NULL;
442 }
443
444 void
445 CheckDefaultMap(struct xkb_context *ctx, XkbFile *maps, const char *fileName)
446 {
447     XkbFile *dflt = NULL, *tmp;
448
449     for (tmp = maps; tmp; tmp = (XkbFile *) tmp->common.next) {
450         if (!(tmp->flags & XkbLC_Default))
451             continue;
452         if (!dflt) {
453             dflt = tmp;
454             continue;
455         }
456
457         log_lvl(ctx, 3,
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)"));
463
464         tmp->flags &= (~XkbLC_Default);
465     }
466 }
467
468 /*
469  * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
470  * wildcards.
471  */
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
477 };
478
479 static void
480 EnsureSafeMapName(char *name)
481 {
482     if (!name)
483         return;
484
485     while (*name != '\0') {
486         if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0)
487             *name = '_';
488         name++;
489     }
490 }
491
492 XkbFile *
493 CreateXKBFile(struct xkb_context *ctx, enum xkb_file_type type, char *name,
494               ParseCommon *defs, unsigned flags)
495 {
496     XkbFile *file;
497
498     file = calloc(1, sizeof(*file));
499     if (!file)
500         return NULL;
501
502     EnsureSafeMapName(name);
503     file->file_type = type;
504     file->topName = strdup_safe(name);
505     file->name = name;
506     file->defs = defs;
507     file->id = xkb_context_take_file_id(ctx);
508     file->flags = flags;
509     return file;
510 }
511
512 static void
513 FreeExpr(ExprDef *expr)
514 {
515     char **sym;
516
517     if (!expr)
518         return;
519
520     switch (expr->op) {
521     case EXPR_ACTION_LIST:
522     case EXPR_NEGATE:
523     case EXPR_UNARY_PLUS:
524     case EXPR_NOT:
525     case EXPR_INVERT:
526         FreeStmt(&expr->value.child->common);
527         break;
528
529     case EXPR_DIVIDE:
530     case EXPR_ADD:
531     case EXPR_SUBTRACT:
532     case EXPR_MULTIPLY:
533     case EXPR_ASSIGN:
534         FreeStmt(&expr->value.binary.left->common);
535         FreeStmt(&expr->value.binary.right->common);
536         break;
537
538     case EXPR_ACTION_DECL:
539         FreeStmt(&expr->value.action.args->common);
540         break;
541
542     case EXPR_ARRAY_REF:
543         FreeStmt(&expr->value.array.entry->common);
544         break;
545
546     case EXPR_KEYSYM_LIST:
547         darray_foreach(sym, expr->value.list.syms)
548             free(*sym);
549         darray_free(expr->value.list.syms);
550         darray_free(expr->value.list.symsMapIndex);
551         darray_free(expr->value.list.symsNumEntries);
552         break;
553
554     default:
555         break;
556     }
557 }
558
559 static void
560 FreeInclude(IncludeStmt *incl)
561 {
562     IncludeStmt *next;
563
564     while (incl)
565     {
566         next = incl->next_incl;
567
568         free(incl->file);
569         free(incl->map);
570         free(incl->modifier);
571         free(incl->stmt);
572
573         free(incl);
574         incl = next;
575     }
576 }
577
578 void
579 FreeStmt(ParseCommon *stmt)
580 {
581     ParseCommon *next;
582     YYSTYPE u;
583
584     while (stmt)
585     {
586         next = stmt->next;
587         u.any = stmt;
588
589         switch (stmt->type) {
590         case STMT_INCLUDE:
591             FreeInclude((IncludeStmt *) stmt);
592             /* stmt is already free'd here. */
593             stmt = NULL;
594             break;
595         case STMT_EXPR:
596             FreeExpr(u.expr);
597             break;
598         case STMT_VAR:
599             FreeStmt(&u.var->name->common);
600             FreeStmt(&u.var->value->common);
601             break;
602         case STMT_TYPE:
603             FreeStmt(&u.keyType->body->common);
604             break;
605         case STMT_INTERP:
606             free(u.interp->sym);
607             FreeStmt(&u.interp->match->common);
608             FreeStmt(&u.interp->def->common);
609             break;
610         case STMT_VMOD:
611             FreeStmt(&u.vmod->value->common);
612             break;
613         case STMT_SYMBOLS:
614             FreeStmt(&u.syms->symbols->common);
615             break;
616         case STMT_MODMAP:
617             FreeStmt(&u.modMask->keys->common);
618             break;
619         case STMT_GROUP_COMPAT:
620             FreeStmt(&u.groupCompat->def->common);
621             break;
622         case STMT_INDICATOR_MAP:
623             FreeStmt(&u.ledMap->body->common);
624             break;
625         case STMT_INDICATOR_NAME:
626             FreeStmt(&u.ledName->name->common);
627             break;
628         default:
629             break;
630         }
631
632         free(stmt);
633         stmt = next;
634     }
635 }
636
637 void
638 FreeXKBFile(XkbFile *file)
639 {
640     XkbFile *next;
641
642     while (file)
643     {
644         next = (XkbFile *) file->common.next;
645
646         switch (file->file_type) {
647         case FILE_TYPE_KEYMAP:
648             FreeXKBFile((XkbFile *) file->defs);
649             break;
650
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);
657             break;
658
659         default:
660             break;
661         }
662
663         free(file->name);
664         free(file->topName);
665         free(file);
666         file = next;
667     }
668 }
669
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",
685 };
686
687 const char *
688 StmtTypeToString(enum stmt_type type)
689 {
690     if (type >= _STMT_NUM_VALUES)
691         type = STMT_UNKNOWN;
692     return stmt_type_strings[type];
693 }