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