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