7a6afa7a03b11a97cd02f5844302ee8fedbda4e5
[profile/ivi/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 ParseCommon *
31 AppendStmt(ParseCommon * to, ParseCommon * append)
32 {
33     ParseCommon *start = to;
34
35     if (append == NULL)
36         return to;
37     while ((to != NULL) && (to->next != NULL))
38     {
39         to = to->next;
40     }
41     if (to)
42     {
43         to->next = append;
44         return start;
45     }
46     return append;
47 }
48
49 ExprDef *
50 ExprCreate(unsigned op, unsigned type)
51 {
52     ExprDef *expr;
53     expr = uTypedAlloc(ExprDef);
54     if (expr)
55     {
56         expr->common.stmtType = StmtExpr;
57         expr->common.next = NULL;
58         expr->op = op;
59         expr->type = type;
60     }
61     else
62     {
63         FATAL("Couldn't allocate expression in parser\n");
64         /* NOTREACHED */
65     }
66     return expr;
67 }
68
69 ExprDef *
70 ExprCreateUnary(unsigned op, unsigned type, ExprDef * child)
71 {
72     ExprDef *expr;
73     expr = uTypedAlloc(ExprDef);
74     if (expr)
75     {
76         expr->common.stmtType = StmtExpr;
77         expr->common.next = NULL;
78         expr->op = op;
79         expr->type = type;
80         expr->value.child = child;
81     }
82     else
83     {
84         FATAL("Couldn't allocate expression in parser\n");
85         /* NOTREACHED */
86     }
87     return expr;
88 }
89
90 ExprDef *
91 ExprCreateBinary(unsigned op, ExprDef * left, ExprDef * right)
92 {
93     ExprDef *expr;
94     expr = uTypedAlloc(ExprDef);
95     if (expr)
96     {
97         expr->common.stmtType = StmtExpr;
98         expr->common.next = NULL;
99         expr->op = op;
100         if ((op == OpAssign) || (left->type == TypeUnknown))
101             expr->type = right->type;
102         else if ((left->type == right->type) || (right->type == TypeUnknown))
103             expr->type = left->type;
104         else
105             expr->type = TypeUnknown;
106         expr->value.binary.left = left;
107         expr->value.binary.right = right;
108     }
109     else
110     {
111         FATAL("Couldn't allocate expression in parser\n");
112         /* NOTREACHED */
113     }
114     return expr;
115 }
116
117 KeycodeDef *
118 KeycodeCreate(const char *name, unsigned long value)
119 {
120     KeycodeDef *def;
121
122     def = uTypedAlloc(KeycodeDef);
123     if (def)
124     {
125         def->common.stmtType = StmtKeycodeDef;
126         def->common.next = NULL;
127         strncpy(def->name, name, XkbKeyNameLength);
128         def->name[XkbKeyNameLength] = '\0';
129         def->value = value;
130     }
131     else
132     {
133         FATAL("Couldn't allocate key name definition in parser\n");
134         /* NOTREACHED */
135     }
136     return def;
137 }
138
139 KeyAliasDef *
140 KeyAliasCreate(const char *alias, const char *real)
141 {
142     KeyAliasDef *def;
143
144     def = uTypedAlloc(KeyAliasDef);
145     if (def)
146     {
147         def->common.stmtType = StmtKeyAliasDef;
148         def->common.next = NULL;
149         strncpy(def->alias, alias, XkbKeyNameLength);
150         def->alias[XkbKeyNameLength] = '\0';
151         strncpy(def->real, real, XkbKeyNameLength);
152         def->real[XkbKeyNameLength] = '\0';
153     }
154     else
155     {
156         FATAL("Couldn't allocate key alias definition in parser\n");
157         /* NOTREACHED */
158     }
159     return def;
160 }
161
162 VModDef *
163 VModCreate(xkb_atom_t name, ExprDef * value)
164 {
165     VModDef *def;
166     def = uTypedAlloc(VModDef);
167     if (def)
168     {
169         def->common.stmtType = StmtVModDef;
170         def->common.next = NULL;
171         def->name = name;
172         def->value = value;
173     }
174     else
175     {
176         FATAL("Couldn't allocate variable definition in parser\n");
177         /* NOTREACHED */
178     }
179     return def;
180 }
181
182 VarDef *
183 VarCreate(ExprDef * name, ExprDef * value)
184 {
185     VarDef *def;
186     def = uTypedAlloc(VarDef);
187     if (def)
188     {
189         def->common.stmtType = StmtVarDef;
190         def->common.next = NULL;
191         def->name = name;
192         def->value = value;
193     }
194     else
195     {
196         FATAL("Couldn't allocate variable definition in parser\n");
197         /* NOTREACHED */
198     }
199     return def;
200 }
201
202 VarDef *
203 BoolVarCreate(xkb_atom_t nameToken, unsigned set)
204 {
205     ExprDef *name, *value;
206
207     name = ExprCreate(ExprIdent, TypeUnknown);
208     name->value.str = nameToken;
209     value = ExprCreate(ExprValue, TypeBoolean);
210     value->value.uval = set;
211     return VarCreate(name, value);
212 }
213
214 InterpDef *
215 InterpCreate(char *sym, ExprDef * match)
216 {
217     InterpDef *def;
218
219     def = uTypedAlloc(InterpDef);
220     if (def)
221     {
222         def->common.stmtType = StmtInterpDef;
223         def->common.next = NULL;
224         def->sym = sym;
225         def->match = match;
226     }
227     else
228     {
229         FATAL("Couldn't allocate interp definition in parser\n");
230         /* NOTREACHED */
231     }
232     return def;
233 }
234
235 KeyTypeDef *
236 KeyTypeCreate(xkb_atom_t name, VarDef * body)
237 {
238     KeyTypeDef *def;
239
240     def = uTypedAlloc(KeyTypeDef);
241     if (def)
242     {
243         def->common.stmtType = StmtKeyTypeDef;
244         def->common.next = NULL;
245         def->merge = MergeDefault;
246         def->name = name;
247         def->body = body;
248     }
249     else
250     {
251         FATAL("Couldn't allocate key type definition in parser\n");
252         /* NOTREACHED */
253     }
254     return def;
255 }
256
257 SymbolsDef *
258 SymbolsCreate(const char *keyName, ExprDef *symbols)
259 {
260     SymbolsDef *def;
261
262     def = uTypedAlloc(SymbolsDef);
263     if (def)
264     {
265         def->common.stmtType = StmtSymbolsDef;
266         def->common.next = NULL;
267         def->merge = MergeDefault;
268         memset(def->keyName, 0, 5);
269         strncpy(def->keyName, keyName, 4);
270         def->symbols = symbols;
271     }
272     else
273     {
274         FATAL("Couldn't allocate symbols definition in parser\n");
275         /* NOTREACHED */
276     }
277     return def;
278 }
279
280 GroupCompatDef *
281 GroupCompatCreate(int group, ExprDef * val)
282 {
283     GroupCompatDef *def;
284
285     def = uTypedAlloc(GroupCompatDef);
286     if (def)
287     {
288         def->common.stmtType = StmtGroupCompatDef;
289         def->common.next = NULL;
290         def->merge = MergeDefault;
291         def->group = group;
292         def->def = val;
293     }
294     else
295     {
296         FATAL("Couldn't allocate group compat definition in parser\n");
297         /* NOTREACHED */
298     }
299     return def;
300 }
301
302 ModMapDef *
303 ModMapCreate(uint32_t modifier, ExprDef * keys)
304 {
305     ModMapDef *def;
306
307     def = uTypedAlloc(ModMapDef);
308     if (def)
309     {
310         def->common.stmtType = StmtModMapDef;
311         def->common.next = NULL;
312         def->merge = MergeDefault;
313         def->modifier = modifier;
314         def->keys = keys;
315     }
316     else
317     {
318         FATAL("Couldn't allocate mod mask definition in parser\n");
319         /* NOTREACHED */
320     }
321     return def;
322 }
323
324 IndicatorMapDef *
325 IndicatorMapCreate(xkb_atom_t name, VarDef * body)
326 {
327     IndicatorMapDef *def;
328
329     def = uTypedAlloc(IndicatorMapDef);
330     if (def)
331     {
332         def->common.stmtType = StmtIndicatorMapDef;
333         def->common.next = NULL;
334         def->merge = MergeDefault;
335         def->name = name;
336         def->body = body;
337     }
338     else
339     {
340         FATAL("Couldn't allocate indicator map definition in parser\n");
341         /* NOTREACHED */
342     }
343     return def;
344 }
345
346 IndicatorNameDef *
347 IndicatorNameCreate(int ndx, ExprDef * name, bool virtual)
348 {
349     IndicatorNameDef *def;
350
351     def = uTypedAlloc(IndicatorNameDef);
352     if (def)
353     {
354         def->common.stmtType = StmtIndicatorNameDef;
355         def->common.next = NULL;
356         def->merge = MergeDefault;
357         def->ndx = ndx;
358         def->name = name;
359         def->virtual = virtual;
360     }
361     else
362     {
363         FATAL("Couldn't allocate indicator index definition in parser\n");
364         /* NOTREACHED */
365     }
366     return def;
367 }
368
369 ExprDef *
370 ActionCreate(xkb_atom_t name, ExprDef * args)
371 {
372     ExprDef *act;
373
374     act = uTypedAlloc(ExprDef);
375     if (act)
376     {
377         act->common.stmtType = StmtExpr;
378         act->common.next = NULL;
379         act->op = ExprActionDecl;
380         act->value.action.name = name;
381         act->value.action.args = args;
382         return act;
383     }
384     FATAL("Couldn't allocate ActionDef in parser\n");
385     return NULL;
386 }
387
388 ExprDef *
389 CreateKeysymList(char *sym)
390 {
391     ExprDef *def;
392
393     def = ExprCreate(ExprKeysymList, TypeSymbols);
394     if (!def)
395     {
396         FATAL("Couldn't allocate expression for keysym list in parser\n");
397         return NULL;
398     }
399
400     darray_init(def->value.list.syms);
401     darray_init(def->value.list.symsMapIndex);
402     darray_init(def->value.list.symsNumEntries);
403
404     darray_append(def->value.list.syms, sym);
405     darray_append(def->value.list.symsMapIndex, 0);
406     darray_append(def->value.list.symsNumEntries, 1);
407
408     return def;
409 }
410
411 ExprDef *
412 CreateMultiKeysymList(ExprDef *list)
413 {
414     size_t nLevels = darray_size(list->value.list.symsMapIndex);
415
416     darray_resize(list->value.list.symsMapIndex, 1);
417     darray_resize(list->value.list.symsNumEntries, 1);
418     darray_item(list->value.list.symsMapIndex, 0) = 0;
419     darray_item(list->value.list.symsNumEntries, 0) = nLevels;
420
421     return list;
422 }
423
424 ExprDef *
425 AppendKeysymList(ExprDef * list, char *sym)
426 {
427     size_t nSyms = darray_size(list->value.list.syms);
428
429     darray_append(list->value.list.symsMapIndex, nSyms);
430     darray_append(list->value.list.symsNumEntries, 1);
431     darray_append(list->value.list.syms, sym);
432
433     return list;
434 }
435
436 ExprDef *
437 AppendMultiKeysymList(ExprDef * list, ExprDef * append)
438 {
439     size_t nSyms = darray_size(list->value.list.syms);
440     size_t numEntries = darray_size(append->value.list.syms);
441
442     darray_append(list->value.list.symsMapIndex, nSyms);
443     darray_append(list->value.list.symsNumEntries, numEntries);
444     darray_append_items(list->value.list.syms,
445                         &darray_item(append->value.list.syms, 0),
446                         numEntries);
447
448     darray_resize(append->value.list.syms, 0);
449     FreeStmt(&append->common);
450
451     return list;
452 }
453
454 int
455 LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn)
456 {
457     xkb_keysym_t sym;
458
459     if ((!str) || (strcasecmp(str, "any") == 0) ||
460         (strcasecmp(str, "nosymbol") == 0))
461     {
462         *sym_rtrn = XKB_KEY_NoSymbol;
463         return 1;
464     }
465     else if ((strcasecmp(str, "none") == 0) ||
466              (strcasecmp(str, "voidsymbol") == 0))
467     {
468         *sym_rtrn = XKB_KEY_VoidSymbol;
469         return 1;
470     }
471     sym = xkb_keysym_from_name(str);
472     if (sym != XKB_KEY_NoSymbol)
473     {
474         *sym_rtrn = sym;
475         return 1;
476     }
477     return 0;
478 }
479
480 static void
481 FreeInclude(IncludeStmt *incl);
482
483 IncludeStmt *
484 IncludeCreate(char *str, unsigned merge)
485 {
486     IncludeStmt *incl, *first;
487     char *file, *map, *stmt, *tmp, *extra_data;
488     char nextop;
489     bool haveSelf;
490
491     haveSelf = false;
492     incl = first = NULL;
493     file = map = NULL;
494     tmp = str;
495     stmt = uDupString(str);
496     while ((tmp) && (*tmp))
497     {
498         if (XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
499         {
500             if ((file == NULL) && (map == NULL))
501             {
502                 if (haveSelf)
503                     goto BAIL;
504                 haveSelf = true;
505             }
506             if (first == NULL)
507                 first = incl = uTypedAlloc(IncludeStmt);
508             else
509             {
510                 incl->next = uTypedAlloc(IncludeStmt);
511                 incl = incl->next;
512             }
513             if (incl)
514             {
515                 incl->common.stmtType = StmtInclude;
516                 incl->common.next = NULL;
517                 incl->merge = merge;
518                 incl->stmt = NULL;
519                 incl->file = file;
520                 incl->map = map;
521                 incl->modifier = extra_data;
522                 incl->path = NULL;
523                 incl->next = NULL;
524             }
525             else
526             {
527                 WSGO("Allocation failure in IncludeCreate\n");
528                 ACTION("Using only part of the include\n");
529                 break;
530             }
531             if (nextop == '|')
532                 merge = MergeAugment;
533             else
534                 merge = MergeOverride;
535         }
536         else
537         {
538             goto BAIL;
539         }
540     }
541     if (first)
542         first->stmt = stmt;
543     else
544         free(stmt);
545     return first;
546
547 BAIL:
548     ERROR("Illegal include statement \"%s\"\n", stmt);
549     ACTION("Ignored\n");
550     FreeInclude(first);
551     free(stmt);
552     return NULL;
553 }
554
555 void
556 CheckDefaultMap(XkbFile * maps, const char *fileName)
557 {
558     XkbFile *dflt, *tmp;
559
560     dflt = NULL;
561     for (tmp = maps, dflt = NULL; tmp != NULL;
562          tmp = (XkbFile *) tmp->common.next)
563     {
564         if (tmp->flags & XkbLC_Default)
565         {
566             if (dflt == NULL)
567                 dflt = tmp;
568             else
569             {
570                 if (warningLevel > 2)
571                 {
572                     WARN("Multiple default components in %s\n",
573                           (fileName ? fileName : "(unknown)"));
574                     ACTION("Using %s, ignoring %s\n",
575                             (dflt->name ? dflt->name : "(first)"),
576                             (tmp->name ? tmp->name : "(subsequent)"));
577                 }
578                 tmp->flags &= (~XkbLC_Default);
579             }
580         }
581     }
582 }
583
584 /*
585  * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
586  * wildcards.
587  */
588 static const unsigned char componentSpecLegal[] = {
589     0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
590     0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
591     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592     0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
593 };
594
595 static void
596 EnsureSafeMapName(char *name)
597 {
598     if (!name)
599         return;
600
601     while (*name!='\0') {
602         if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0)
603             *name= '_';
604         name++;
605     }
606 }
607
608 XkbFile *
609 CreateXKBFile(struct xkb_context *ctx, int type, char *name,
610               ParseCommon *defs, unsigned flags)
611 {
612     XkbFile *file;
613
614     file = uTypedAlloc(XkbFile);
615     if (file)
616     {
617         EnsureSafeMapName(name);
618         memset(file, 0, sizeof(XkbFile));
619         file->type = type;
620         file->topName = uDupString(name);
621         file->name = name;
622         file->defs = defs;
623         file->id = xkb_context_take_file_id(ctx);
624         file->flags = flags;
625     }
626     return file;
627 }
628
629 unsigned
630 StmtSetMerge(ParseCommon * stmt, unsigned merge, struct YYLTYPE *loc, void *scanner)
631 {
632     if ((merge == MergeAltForm) && (stmt->stmtType != StmtKeycodeDef))
633     {
634         yyerror(loc, scanner, "illegal use of 'alternate' merge mode");
635         merge = MergeDefault;
636     }
637     return merge;
638 }
639
640 static void
641 FreeExpr(ExprDef *expr)
642 {
643     char **sym;
644
645     if (!expr)
646         return;
647
648     switch (expr->op)
649     {
650     case ExprActionList:
651     case OpNegate:
652     case OpUnaryPlus:
653     case OpNot:
654     case OpInvert:
655         FreeStmt(&expr->value.child->common);
656         break;
657     case OpDivide:
658     case OpAdd:
659     case OpSubtract:
660     case OpMultiply:
661     case OpAssign:
662         FreeStmt(&expr->value.binary.left->common);
663         FreeStmt(&expr->value.binary.right->common);
664         break;
665     case ExprActionDecl:
666         FreeStmt(&expr->value.action.args->common);
667         break;
668     case ExprArrayRef:
669         FreeStmt(&expr->value.array.entry->common);
670         break;
671     case ExprKeysymList:
672         darray_foreach(sym, expr->value.list.syms)
673             free(*sym);
674         darray_free(expr->value.list.syms);
675         darray_free(expr->value.list.symsMapIndex);
676         darray_free(expr->value.list.symsNumEntries);
677         break;
678     default:
679         break;
680     }
681 }
682
683 static void
684 FreeInclude(IncludeStmt *incl)
685 {
686     IncludeStmt *next;
687
688     while (incl)
689     {
690         next = incl->next;
691
692         free(incl->file);
693         free(incl->map);
694         free(incl->modifier);
695         free(incl->path);
696         free(incl->stmt);
697
698         free(incl);
699         incl = next;
700     }
701 }
702
703 void
704 FreeStmt(ParseCommon *stmt)
705 {
706     ParseCommon *next;
707     YYSTYPE u;
708
709     while (stmt)
710     {
711         next = stmt->next;
712         u.any = stmt;
713
714         switch (stmt->stmtType)
715         {
716         case StmtInclude:
717             FreeInclude((IncludeStmt *)stmt);
718             /* stmt is already free'd here. */
719             stmt = NULL;
720             break;
721         case StmtExpr:
722             FreeExpr(u.expr);
723             break;
724         case StmtVarDef:
725             FreeStmt(&u.var->name->common);
726             FreeStmt(&u.var->value->common);
727             break;
728         case StmtKeyTypeDef:
729             FreeStmt(&u.keyType->body->common);
730             break;
731         case StmtInterpDef:
732             free(u.interp->sym);
733             FreeStmt(&u.interp->match->common);
734             FreeStmt(&u.interp->def->common);
735             break;
736         case StmtVModDef:
737             FreeStmt(&u.vmod->value->common);
738             break;
739         case StmtSymbolsDef:
740             FreeStmt(&u.syms->symbols->common);
741             break;
742         case StmtModMapDef:
743             FreeStmt(&u.modMask->keys->common);
744             break;
745         case StmtGroupCompatDef:
746             FreeStmt(&u.groupCompat->def->common);
747             break;
748         case StmtIndicatorMapDef:
749             FreeStmt(&u.ledMap->body->common);
750             break;
751         case StmtIndicatorNameDef:
752             FreeStmt(&u.ledName->name->common);
753             break;
754         default:
755             break;
756         }
757
758         free(stmt);
759         stmt = next;
760     }
761 }
762
763 void
764 FreeXKBFile(XkbFile *file)
765 {
766     XkbFile *next;
767
768     while (file)
769     {
770         next = (XkbFile *)file->common.next;
771
772         switch (file->type)
773         {
774         case XkmKeymapFile:
775             FreeXKBFile((XkbFile *)file->defs);
776             break;
777         case XkmTypesIndex:
778         case XkmCompatMapIndex:
779         case XkmSymbolsIndex:
780         case XkmKeyNamesIndex:
781         case XkmGeometryIndex:
782             FreeStmt(file->defs);
783             break;
784         }
785
786         free(file->name);
787         free(file->topName);
788         free(file);
789         file = next;
790     }
791 }