Perform bounds checking in ExprResolveLevel
[platform/upstream/libxkbcommon.git] / src / xkbcomp / keytypes.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.h"
28 #include "xkballoc.h"
29 #include "xkbmisc.h"
30 #include "tokens.h"
31 #include "expr.h"
32 #include "vmod.h"
33 #include "action.h"
34 #include "misc.h"
35
36 typedef struct _PreserveInfo
37 {
38     CommonInfo defs;
39     short matchingMapIndex;
40     unsigned char indexMods;
41     unsigned char preMods;
42     unsigned short indexVMods;
43     unsigned short preVMods;
44 } PreserveInfo;
45
46 #define _KT_Name        (1<<0)
47 #define _KT_Mask        (1<<1)
48 #define _KT_Map         (1<<2)
49 #define _KT_Preserve    (1<<3)
50 #define _KT_LevelNames  (1<<4)
51
52 typedef struct _KeyTypeInfo
53 {
54     CommonInfo defs;
55     uint32_t name;
56     int fileID;
57     unsigned mask;
58     unsigned vmask;
59     Bool groupInfo;
60     int numLevels;
61     int nEntries;
62     int szEntries;
63     struct xkb_kt_map_entry * entries;
64     PreserveInfo *preserve;
65     int szNames;
66     uint32_t *lvlNames;
67 } KeyTypeInfo;
68
69 typedef struct _KeyTypesInfo
70 {
71     char *name;
72     int errorCount;
73     int fileID;
74     unsigned stdPresent;
75     int nTypes;
76     KeyTypeInfo *types;
77     KeyTypeInfo dflt;
78     VModInfo vmods;
79 } KeyTypesInfo;
80
81 uint32_t tok_ONE_LEVEL;
82 uint32_t tok_TWO_LEVEL;
83 static uint32_t tok_ALPHABETIC;
84 uint32_t tok_KEYPAD;
85
86 /***====================================================================***/
87
88 #define ReportTypeShouldBeArray(t, f) \
89     ReportShouldBeArray("key type", (f), TypeTxt(t))
90 #define ReportTypeBadType(t, f, w) \
91     ReportBadType("key type", (f), TypeTxt(t), (w))
92
93 /***====================================================================***/
94
95 #define MapEntryTxt(x, e) \
96     XkbcVModMaskText((x), (e)->mods.real_mods, (e)->mods.vmods)
97 #define PreserveIndexTxt(x, p) \
98     XkbcVModMaskText((x), (p)->indexMods, (p)->indexVMods)
99 #define PreserveTxt(x, p) \
100     XkbcVModMaskText((x), (p)->preMods, (p)->preVMods)
101 #define TypeTxt(t) \
102     XkbcAtomText((t)->name)
103 #define TypeMaskTxt(t, x) \
104     XkbcVModMaskText((x), (t)->mask, (t)->vmask)
105
106 /***====================================================================***/
107
108 static void
109 InitKeyTypesInfo(KeyTypesInfo * info, struct xkb_desc * xkb, KeyTypesInfo * from)
110 {
111     tok_ONE_LEVEL = xkb_intern_atom("ONE_LEVEL");
112     tok_TWO_LEVEL = xkb_intern_atom("TWO_LEVEL");
113     tok_ALPHABETIC = xkb_intern_atom("ALPHABETIC");
114     tok_KEYPAD = xkb_intern_atom("KEYPAD");
115     info->name = strdup("default");
116     info->errorCount = 0;
117     info->stdPresent = 0;
118     info->nTypes = 0;
119     info->types = NULL;
120     info->dflt.defs.defined = 0;
121     info->dflt.defs.fileID = 0;
122     info->dflt.defs.merge = MergeOverride;
123     info->dflt.defs.next = NULL;
124     info->dflt.name = None;
125     info->dflt.mask = 0;
126     info->dflt.vmask = 0;
127     info->dflt.groupInfo = False;
128     info->dflt.numLevels = 1;
129     info->dflt.nEntries = info->dflt.szEntries = 0;
130     info->dflt.entries = NULL;
131     info->dflt.szNames = 0;
132     info->dflt.lvlNames = NULL;
133     info->dflt.preserve = NULL;
134     InitVModInfo(&info->vmods, xkb);
135     if (from != NULL)
136     {
137         info->dflt = from->dflt;
138         if (from->dflt.entries)
139         {
140             info->dflt.entries = uTypedCalloc(from->dflt.szEntries,
141                                               struct xkb_kt_map_entry);
142             if (info->dflt.entries)
143             {
144                 unsigned sz = from->dflt.nEntries * sizeof(struct xkb_kt_map_entry);
145                 memcpy(info->dflt.entries, from->dflt.entries, sz);
146             }
147         }
148         if (from->dflt.lvlNames)
149         {
150             info->dflt.lvlNames = uTypedCalloc(from->dflt.szNames, uint32_t);
151             if (info->dflt.lvlNames)
152             {
153                 register unsigned sz = from->dflt.szNames * sizeof(uint32_t);
154                 memcpy(info->dflt.lvlNames, from->dflt.lvlNames, sz);
155             }
156         }
157         if (from->dflt.preserve)
158         {
159             PreserveInfo *old, *new, *last;
160             last = NULL;
161             old = from->dflt.preserve;
162             for (; old; old = (PreserveInfo *) old->defs.next)
163             {
164                 new = uTypedAlloc(PreserveInfo);
165                 if (!new)
166                     return;
167                 *new = *old;
168                 new->defs.next = NULL;
169                 if (last)
170                     last->defs.next = (CommonInfo *) new;
171                 else
172                     info->dflt.preserve = new;
173                 last = new;
174             }
175         }
176     }
177     return;
178 }
179
180 static void
181 FreeKeyTypeInfo(KeyTypeInfo * type)
182 {
183     if (type->entries != NULL)
184     {
185         free(type->entries);
186         type->entries = NULL;
187     }
188     if (type->lvlNames != NULL)
189     {
190         free(type->lvlNames);
191         type->lvlNames = NULL;
192     }
193     if (type->preserve != NULL)
194     {
195         ClearCommonInfo(&type->preserve->defs);
196         type->preserve = NULL;
197     }
198     return;
199 }
200
201 static void
202 FreeKeyTypesInfo(KeyTypesInfo * info)
203 {
204     if (info->name)
205         free(info->name);
206     info->name = NULL;
207     if (info->types)
208     {
209         register KeyTypeInfo *type;
210         for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
211         {
212             FreeKeyTypeInfo(type);
213         }
214         info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs);
215     }
216     FreeKeyTypeInfo(&info->dflt);
217     return;
218 }
219
220 static KeyTypeInfo *
221 NextKeyType(KeyTypesInfo * info)
222 {
223     KeyTypeInfo *type;
224
225     type = uTypedAlloc(KeyTypeInfo);
226     if (type != NULL)
227     {
228         bzero(type, sizeof(KeyTypeInfo));
229         type->defs.fileID = info->fileID;
230         info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs,
231                                                     (CommonInfo *) type);
232         info->nTypes++;
233     }
234     return type;
235 }
236
237 static KeyTypeInfo *
238 FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
239 {
240     KeyTypeInfo *old;
241
242     for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
243     {
244         if (old->name == new->name)
245             return old;
246     }
247     return NULL;
248 }
249
250 static Bool
251 ReportTypeBadWidth(const char *type, int has, int needs)
252 {
253     ERROR("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
254     ACTION("Illegal type definition ignored\n");
255     return False;
256 }
257
258 static Bool
259 AddKeyType(struct xkb_desc * xkb, KeyTypesInfo * info, KeyTypeInfo * new)
260 {
261     KeyTypeInfo *old;
262
263     if (new->name == tok_ONE_LEVEL)
264     {
265         if (new->numLevels > 1)
266             return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
267         info->stdPresent |= XkbOneLevelMask;
268     }
269     else if (new->name == tok_TWO_LEVEL)
270     {
271         if (new->numLevels > 2)
272             return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
273         else if (new->numLevels < 2)
274             new->numLevels = 2;
275         info->stdPresent |= XkbTwoLevelMask;
276     }
277     else if (new->name == tok_ALPHABETIC)
278     {
279         if (new->numLevels > 2)
280             return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
281         else if (new->numLevels < 2)
282             new->numLevels = 2;
283         info->stdPresent |= XkbAlphabeticMask;
284     }
285     else if (new->name == tok_KEYPAD)
286     {
287         if (new->numLevels > 2)
288             return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
289         else if (new->numLevels < 2)
290             new->numLevels = 2;
291         info->stdPresent |= XkbKeypadMask;
292     }
293
294     old = FindMatchingKeyType(info, new);
295     if (old != NULL)
296     {
297         Bool report;
298         if ((new->defs.merge == MergeReplace)
299             || (new->defs.merge == MergeOverride))
300         {
301             KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
302             if (((old->defs.fileID == new->defs.fileID)
303                  && (warningLevel > 0)) || (warningLevel > 9))
304             {
305                 WARN("Multiple definitions of the %s key type\n",
306                      XkbcAtomText(new->name));
307                 ACTION("Earlier definition ignored\n");
308             }
309             FreeKeyTypeInfo(old);
310             *old = *new;
311             new->szEntries = new->nEntries = 0;
312             new->entries = NULL;
313             new->preserve = NULL;
314             new->lvlNames = NULL;
315             old->defs.next = &next->defs;
316             return True;
317         }
318         report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
319         if (report)
320         {
321             WARN("Multiple definitions of the %s key type\n",
322                  XkbcAtomText(new->name));
323             ACTION("Later definition ignored\n");
324         }
325         FreeKeyTypeInfo(new);
326         return True;
327     }
328     old = NextKeyType(info);
329     if (old == NULL)
330         return False;
331     *old = *new;
332     old->defs.next = NULL;
333     new->nEntries = new->szEntries = 0;
334     new->entries = NULL;
335     new->szNames = 0;
336     new->lvlNames = NULL;
337     new->preserve = NULL;
338     return True;
339 }
340
341 /***====================================================================***/
342
343 static void
344 MergeIncludedKeyTypes(KeyTypesInfo * into,
345                       KeyTypesInfo * from, unsigned merge, struct xkb_desc * xkb)
346 {
347     KeyTypeInfo *type;
348
349     if (from->errorCount > 0)
350     {
351         into->errorCount += from->errorCount;
352         return;
353     }
354     if (into->name == NULL)
355     {
356         into->name = from->name;
357         from->name = NULL;
358     }
359     for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
360     {
361         if (merge != MergeDefault)
362             type->defs.merge = merge;
363         if (!AddKeyType(xkb, into, type))
364             into->errorCount++;
365     }
366     into->stdPresent |= from->stdPresent;
367     return;
368 }
369
370 typedef void (*FileHandler) (XkbFile * /* file */ ,
371                              struct xkb_desc * /* xkb */ ,
372                              unsigned /* merge */ ,
373                              KeyTypesInfo *     /* included */
374     );
375
376 static Bool
377 HandleIncludeKeyTypes(IncludeStmt * stmt,
378                       struct xkb_desc * xkb, KeyTypesInfo * info, FileHandler hndlr)
379 {
380     unsigned newMerge;
381     XkbFile *rtrn;
382     KeyTypesInfo included;
383     Bool haveSelf;
384
385     haveSelf = False;
386     if ((stmt->file == NULL) && (stmt->map == NULL))
387     {
388         haveSelf = True;
389         included = *info;
390         bzero(info, sizeof(KeyTypesInfo));
391     }
392     else if (ProcessIncludeFile(stmt, XkmTypesIndex, &rtrn, &newMerge))
393     {
394         InitKeyTypesInfo(&included, xkb, info);
395         included.fileID = included.dflt.defs.fileID = rtrn->id;
396         included.dflt.defs.merge = newMerge;
397
398         (*hndlr) (rtrn, xkb, newMerge, &included);
399         if (stmt->stmt != NULL)
400         {
401             if (included.name != NULL)
402                 free(included.name);
403             included.name = stmt->stmt;
404             stmt->stmt = NULL;
405         }
406     }
407     else
408     {
409         info->errorCount += 10;
410         return False;
411     }
412     if ((stmt->next != NULL) && (included.errorCount < 1))
413     {
414         IncludeStmt *next;
415         unsigned op;
416         KeyTypesInfo next_incl;
417
418         for (next = stmt->next; next != NULL; next = next->next)
419         {
420             if ((next->file == NULL) && (next->map == NULL))
421             {
422                 haveSelf = True;
423                 MergeIncludedKeyTypes(&included, info, next->merge, xkb);
424                 FreeKeyTypesInfo(info);
425             }
426             else if (ProcessIncludeFile(next, XkmTypesIndex, &rtrn, &op))
427             {
428                 InitKeyTypesInfo(&next_incl, xkb, &included);
429                 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
430                 next_incl.dflt.defs.merge = op;
431                 (*hndlr) (rtrn, xkb, op, &next_incl);
432                 MergeIncludedKeyTypes(&included, &next_incl, op, xkb);
433                 FreeKeyTypesInfo(&next_incl);
434             }
435             else
436             {
437                 info->errorCount += 10;
438                 FreeKeyTypesInfo(&included);
439                 return False;
440             }
441         }
442     }
443     if (haveSelf)
444         *info = included;
445     else
446     {
447         MergeIncludedKeyTypes(info, &included, newMerge, xkb);
448         FreeKeyTypesInfo(&included);
449     }
450     return (info->errorCount == 0);
451 }
452
453 /***====================================================================***/
454
455 static struct xkb_kt_map_entry *
456 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
457 {
458     register int i;
459     struct xkb_kt_map_entry * entry;
460
461     for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
462     {
463         if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
464             return entry;
465     }
466     return NULL;
467 }
468
469 static void
470 DeleteLevel1MapEntries(KeyTypeInfo * type)
471 {
472     register int i, n;
473
474     for (i = 0; i < type->nEntries; i++)
475     {
476         if (type->entries[i].level == 0)
477         {
478             for (n = i; n < type->nEntries - 1; n++)
479             {
480                 type->entries[n] = type->entries[n + 1];
481             }
482             type->nEntries--;
483         }
484     }
485     return;
486 }
487
488 /**
489  * Return a pointer to the next free XkbcKTMapEntry, reallocating space if
490  * necessary.
491  */
492 static struct xkb_kt_map_entry *
493 NextMapEntry(KeyTypeInfo * type)
494 {
495     if (type->entries == NULL)
496     {
497         type->entries = uTypedCalloc(2, struct xkb_kt_map_entry);
498         if (type->entries == NULL)
499         {
500             ERROR("Couldn't allocate map entries for %s\n", TypeTxt(type));
501             ACTION("Map entries lost\n");
502             return NULL;
503         }
504         type->szEntries = 2;
505         type->nEntries = 0;
506     }
507     else if (type->nEntries >= type->szEntries)
508     {
509         type->szEntries *= 2;
510         type->entries = uTypedRecalloc(type->entries,
511                                        type->nEntries, type->szEntries,
512                                        struct xkb_kt_map_entry);
513         if (type->entries == NULL)
514         {
515             ERROR("Couldn't reallocate map entries for %s\n", TypeTxt(type));
516             ACTION("Map entries lost\n");
517             return NULL;
518         }
519     }
520     return &type->entries[type->nEntries++];
521 }
522
523 static Bool
524 AddPreserve(struct xkb_desc * xkb,
525             KeyTypeInfo * type, PreserveInfo * new, Bool clobber, Bool report)
526 {
527     PreserveInfo *old;
528
529     old = type->preserve;
530     while (old != NULL)
531     {
532         if ((old->indexMods != new->indexMods) ||
533             (old->indexVMods != new->indexVMods))
534         {
535             old = (PreserveInfo *) old->defs.next;
536             continue;
537         }
538         if ((old->preMods == new->preMods)
539             && (old->preVMods == new->preVMods))
540         {
541             if (warningLevel > 9)
542             {
543                 WARN("Identical definitions for preserve[%s] in %s\n",
544                       PreserveIndexTxt(xkb, old), TypeTxt(type));
545                 ACTION("Ignored\n");
546             }
547             return True;
548         }
549         if (report && (warningLevel > 0))
550         {
551             char *str;
552             WARN("Multiple definitions for preserve[%s] in %s\n",
553                   PreserveIndexTxt(xkb, old), TypeTxt(type));
554
555             if (clobber)
556                 str = PreserveTxt(xkb, new);
557             else
558                 str = PreserveTxt(xkb, old);
559             ACTION("Using %s, ", str);
560             if (clobber)
561                 str = PreserveTxt(xkb, old);
562             else
563                 str = PreserveTxt(xkb, new);
564             INFO("ignoring %s\n", str);
565         }
566         if (clobber)
567         {
568             old->preMods = new->preMods;
569             old->preVMods = new->preVMods;
570         }
571         return True;
572     }
573     old = uTypedAlloc(PreserveInfo);
574     if (!old)
575     {
576         WSGO("Couldn't allocate preserve in %s\n", TypeTxt(type));
577         ACTION("Preserve[%s] lost\n", PreserveIndexTxt(xkb, old));
578         return False;
579     }
580     *old = *new;
581     old->matchingMapIndex = -1;
582     type->preserve =
583         (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
584     return True;
585 }
586
587 /**
588  * Add a new KTMapEntry to the given key type. If an entry with the same mods
589  * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
590  * entry is created.
591  *
592  * @param clobber Overwrite existing entry.
593  * @param report True if a warning is to be printed on.
594  */
595 static Bool
596 AddMapEntry(struct xkb_desc * xkb,
597             KeyTypeInfo * type,
598             struct xkb_kt_map_entry * new, Bool clobber, Bool report)
599 {
600     struct xkb_kt_map_entry * old;
601
602     if ((old =
603          FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
604     {
605         if (report && (old->level != new->level))
606         {
607             unsigned use, ignore;
608             if (clobber)
609             {
610                 use = new->level + 1;
611                 ignore = old->level + 1;
612             }
613             else
614             {
615                 use = old->level + 1;
616                 ignore = new->level + 1;
617             }
618             WARN("Multiple map entries for %s in %s\n",
619                   MapEntryTxt(xkb, new), TypeTxt(type));
620             ACTION("Using %d, ignoring %d\n", use, ignore);
621         }
622         else if (warningLevel > 9)
623         {
624             WARN("Multiple occurences of map[%s]= %d in %s\n",
625                   MapEntryTxt(xkb, new), new->level + 1, TypeTxt(type));
626             ACTION("Ignored\n");
627             return True;
628         }
629         if (clobber)
630             old->level = new->level;
631         return True;
632     }
633     if ((old = NextMapEntry(type)) == NULL)
634         return False;           /* allocation failure, already reported */
635     if (new->level >= type->numLevels)
636         type->numLevels = new->level + 1;
637     if (new->mods.vmods == 0)
638         old->active = True;
639     else
640         old->active = False;
641     old->mods.mask = new->mods.real_mods;
642     old->mods.real_mods = new->mods.real_mods;
643     old->mods.vmods = new->mods.vmods;
644     old->level = new->level;
645     return True;
646 }
647
648 static Bool
649 SetMapEntry(KeyTypeInfo * type,
650             struct xkb_desc * xkb, ExprDef * arrayNdx, ExprDef * value)
651 {
652     ExprResult rtrn;
653     struct xkb_kt_map_entry entry;
654
655     if (arrayNdx == NULL)
656         return ReportTypeShouldBeArray(type, "map entry");
657     if (!ExprResolveVModMask(arrayNdx, &rtrn, xkb))
658         return ReportTypeBadType(type, "map entry", "modifier mask");
659     entry.mods.real_mods = rtrn.uval & 0xff;      /* modifiers < 512 */
660     entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
661     if ((entry.mods.real_mods & (~type->mask)) ||
662         ((entry.mods.vmods & (~type->vmask)) != 0))
663     {
664         if (warningLevel > 0)
665         {
666             WARN("Map entry for unused modifiers in %s\n", TypeTxt(type));
667             ACTION("Using %s instead of ",
668                     XkbcVModMaskText(xkb,
669                                     entry.mods.real_mods & type->mask,
670                                     entry.mods.vmods & type->vmask));
671             INFO("%s\n", MapEntryTxt(xkb, &entry));
672         }
673         entry.mods.real_mods &= type->mask;
674         entry.mods.vmods &= type->vmask;
675     }
676     if (!ExprResolveLevel(value, &rtrn))
677     {
678         ERROR("Level specifications in a key type must be integer\n");
679         ACTION("Ignoring malformed level specification\n");
680         return False;
681     }
682     entry.level = rtrn.ival - 1;
683     return AddMapEntry(xkb, type, &entry, True, True);
684 }
685
686 static Bool
687 SetPreserve(KeyTypeInfo * type,
688             struct xkb_desc * xkb, ExprDef * arrayNdx, ExprDef * value)
689 {
690     ExprResult rtrn;
691     PreserveInfo new;
692
693     if (arrayNdx == NULL)
694         return ReportTypeShouldBeArray(type, "preserve entry");
695     if (!ExprResolveVModMask(arrayNdx, &rtrn, xkb))
696         return ReportTypeBadType(type, "preserve entry", "modifier mask");
697     new.defs = type->defs;
698     new.defs.next = NULL;
699     new.indexMods = rtrn.uval & 0xff;
700     new.indexVMods = (rtrn.uval >> 8) & 0xffff;
701     if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
702     {
703         if (warningLevel > 0)
704         {
705             WARN("Preserve for modifiers not used by the %s type\n",
706                   TypeTxt(type));
707             ACTION("Index %s converted to ", PreserveIndexTxt(xkb, &new));
708         }
709         new.indexMods &= type->mask;
710         new.indexVMods &= type->vmask;
711         if (warningLevel > 0)
712             INFO("%s\n", PreserveIndexTxt(xkb, &new));
713     }
714     if (!ExprResolveVModMask(value, &rtrn, xkb))
715     {
716         ERROR("Preserve value in a key type is not a modifier mask\n");
717         ACTION("Ignoring preserve[%s] in type %s\n",
718                 PreserveIndexTxt(xkb, &new), TypeTxt(type));
719         return False;
720     }
721     new.preMods = rtrn.uval & 0xff;
722     new.preVMods = (rtrn.uval >> 16) & 0xffff;
723     if ((new.preMods & (~new.indexMods))
724         || (new.preVMods && (~new.indexVMods)))
725     {
726         if (warningLevel > 0)
727         {
728             WARN("Illegal value for preserve[%s] in type %s\n",
729                   PreserveTxt(xkb, &new), TypeTxt(type));
730             ACTION("Converted %s to ", PreserveIndexTxt(xkb, &new));
731         }
732         new.preMods &= new.indexMods;
733         new.preVMods &= new.indexVMods;
734         if (warningLevel > 0)
735         {
736             INFO("%s\n", PreserveIndexTxt(xkb, &new));
737         }
738     }
739     return AddPreserve(xkb, type, &new, True, True);
740 }
741
742 /***====================================================================***/
743
744 static Bool
745 AddLevelName(KeyTypeInfo * type,
746              unsigned level, uint32_t name, Bool clobber, Bool report)
747 {
748     if ((type->lvlNames == NULL) || (type->szNames <= level))
749     {
750         type->lvlNames =
751             uTypedRecalloc(type->lvlNames, type->szNames, level + 1, uint32_t);
752         if (type->lvlNames == NULL)
753         {
754             ERROR("Couldn't allocate level names for type %s\n",
755                    TypeTxt(type));
756             ACTION("Level names lost\n");
757             type->szNames = 0;
758             return False;
759         }
760         type->szNames = level + 1;
761     }
762     else if (type->lvlNames[level] == name)
763     {
764         if (warningLevel > 9)
765         {
766             WARN("Duplicate names for level %d of key type %s\n",
767                   level + 1, TypeTxt(type));
768             ACTION("Ignored\n");
769         }
770         return True;
771     }
772     else if (type->lvlNames[level] != None)
773     {
774         if (warningLevel > 0)
775         {
776             const char *old, *new;
777             old = XkbcAtomText(type->lvlNames[level]);
778             new = XkbcAtomText(name);
779             WARN("Multiple names for level %d of key type %s\n",
780                   level + 1, TypeTxt(type));
781             if (clobber)
782                 ACTION("Using %s, ignoring %s\n", new, old);
783             else
784                 ACTION("Using %s, ignoring %s\n", old, new);
785         }
786         if (!clobber)
787             return True;
788     }
789     if (level >= type->numLevels)
790         type->numLevels = level + 1;
791     type->lvlNames[level] = name;
792     return True;
793 }
794
795 static Bool
796 SetLevelName(KeyTypeInfo * type, ExprDef * arrayNdx, ExprDef * value)
797 {
798     ExprResult rtrn;
799     unsigned level;
800     uint32_t level_name;
801
802     if (arrayNdx == NULL)
803         return ReportTypeShouldBeArray(type, "level name");
804     if (!ExprResolveLevel(arrayNdx, &rtrn))
805         return ReportTypeBadType(type, "level name", "integer");
806     level = rtrn.ival - 1;
807     if (!ExprResolveString(value, &rtrn))
808     {
809         ERROR("Non-string name for level %d in key type %s\n", level + 1,
810                XkbcAtomText(type->name));
811         ACTION("Ignoring illegal level name definition\n");
812         return False;
813     }
814     level_name = xkb_intern_atom(rtrn.str);
815     free(rtrn.str);
816     return AddLevelName(type, level, level_name, True, True);
817 }
818
819 /***====================================================================***/
820
821 /**
822  * Parses the fields in a type "..." { } description.
823  *
824  * @param field The field to parse (e.g. modifiers, map, level_name)
825  */
826 static Bool
827 SetKeyTypeField(KeyTypeInfo * type,
828                 struct xkb_desc * xkb,
829                 char *field,
830                 ExprDef * arrayNdx, ExprDef * value, KeyTypesInfo * info)
831 {
832     ExprResult tmp;
833
834     if (uStrCaseCmp(field, "modifiers") == 0)
835     {
836         unsigned mods, vmods;
837         if (arrayNdx != NULL)
838         {
839             WARN("The modifiers field of a key type is not an array\n");
840             ACTION("Illegal array subscript ignored\n");
841         }
842         /* get modifier mask for current type */
843         if (!ExprResolveVModMask(value, &tmp, xkb))
844         {
845             ERROR("Key type mask field must be a modifier mask\n");
846             ACTION("Key type definition ignored\n");
847             return False;
848         }
849         mods = tmp.uval & 0xff; /* core mods */
850         vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
851         if (type->defs.defined & _KT_Mask)
852         {
853             WARN("Multiple modifier mask definitions for key type %s\n",
854                   XkbcAtomText(type->name));
855             ACTION("Using %s, ", TypeMaskTxt(type, xkb));
856             INFO("ignoring %s\n", XkbcVModMaskText(xkb, mods, vmods));
857             return False;
858         }
859         type->mask = mods;
860         type->vmask = vmods;
861         type->defs.defined |= _KT_Mask;
862         return True;
863     }
864     else if (uStrCaseCmp(field, "map") == 0)
865     {
866         type->defs.defined |= _KT_Map;
867         return SetMapEntry(type, xkb, arrayNdx, value);
868     }
869     else if (uStrCaseCmp(field, "preserve") == 0)
870     {
871         type->defs.defined |= _KT_Preserve;
872         return SetPreserve(type, xkb, arrayNdx, value);
873     }
874     else if ((uStrCaseCmp(field, "levelname") == 0) ||
875              (uStrCaseCmp(field, "level_name") == 0))
876     {
877         type->defs.defined |= _KT_LevelNames;
878         return SetLevelName(type, arrayNdx, value);
879     }
880     ERROR("Unknown field %s in key type %s\n", field, TypeTxt(type));
881     ACTION("Definition ignored\n");
882     return False;
883 }
884
885 static Bool
886 HandleKeyTypeVar(VarDef * stmt, struct xkb_desc * xkb, KeyTypesInfo * info)
887 {
888     ExprResult elem, field;
889     ExprDef *arrayNdx;
890
891     if (!ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx))
892         return False;           /* internal error, already reported */
893     if (elem.str && (uStrCaseCmp(elem.str, "type") == 0))
894         return SetKeyTypeField(&info->dflt, xkb, field.str, arrayNdx,
895                                stmt->value, info);
896     if (elem.str != NULL)
897     {
898         ERROR("Default for unknown element %s\n", uStringText(elem.str));
899         ACTION("Value for field %s ignored\n", uStringText(field.str));
900     }
901     else if (field.str != NULL)
902     {
903         ERROR("Default defined for unknown field %s\n",
904                uStringText(field.str));
905         ACTION("Ignored\n");
906     }
907     return False;
908 }
909
910 static int
911 HandleKeyTypeBody(VarDef * def,
912                   struct xkb_desc * xkb, KeyTypeInfo * type, KeyTypesInfo * info)
913 {
914     int ok = 1;
915     ExprResult tmp, field;
916     ExprDef *arrayNdx;
917
918     for (; def != NULL; def = (VarDef *) def->common.next)
919     {
920         if ((def->name) && (def->name->type == ExprFieldRef))
921         {
922             ok = HandleKeyTypeVar(def, xkb, info);
923             continue;
924         }
925         ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
926         if (ok) {
927             ok = SetKeyTypeField(type, xkb, field.str, arrayNdx, def->value,
928                                  info);
929             free(field.str);
930         }
931     }
932     return ok;
933 }
934
935 /**
936  * Process a type "XYZ" { } specification in the xkb_types section.
937  *
938  */
939 static int
940 HandleKeyTypeDef(KeyTypeDef * def,
941                  struct xkb_desc * xkb, unsigned merge, KeyTypesInfo * info)
942 {
943     register int i;
944     KeyTypeInfo type;
945
946     if (def->merge != MergeDefault)
947         merge = def->merge;
948
949     type.defs.defined = 0;
950     type.defs.fileID = info->fileID;
951     type.defs.merge = merge;
952     type.defs.next = NULL;
953     type.name = def->name;
954     type.mask = info->dflt.mask;
955     type.vmask = info->dflt.vmask;
956     type.groupInfo = info->dflt.groupInfo;
957     type.numLevels = 1;
958     type.nEntries = type.szEntries = 0;
959     type.entries = NULL;
960     type.szNames = 0;
961     type.lvlNames = NULL;
962     type.preserve = NULL;
963
964     /* Parse the actual content. */
965     if (!HandleKeyTypeBody(def->body, xkb, &type, info))
966     {
967         info->errorCount++;
968         return False;
969     }
970
971     /* now copy any appropriate map, preserve or level names from the */
972     /* default type */
973     for (i = 0; i < info->dflt.nEntries; i++)
974     {
975         struct xkb_kt_map_entry * dflt;
976         dflt = &info->dflt.entries[i];
977         if (((dflt->mods.real_mods & type.mask) == dflt->mods.real_mods) &&
978             ((dflt->mods.vmods & type.vmask) == dflt->mods.vmods))
979         {
980             AddMapEntry(xkb, &type, dflt, False, False);
981         }
982     }
983     if (info->dflt.preserve)
984     {
985         PreserveInfo *dflt = info->dflt.preserve;
986         while (dflt)
987         {
988             if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
989                 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
990             {
991                 AddPreserve(xkb, &type, dflt, False, False);
992             }
993             dflt = (PreserveInfo *) dflt->defs.next;
994         }
995     }
996     for (i = 0; i < info->dflt.szNames; i++)
997     {
998         if ((i < type.numLevels) && (info->dflt.lvlNames[i] != None))
999         {
1000             AddLevelName(&type, i, info->dflt.lvlNames[i], False, False);
1001         }
1002     }
1003     /* Now add the new keytype to the info struct */
1004     if (!AddKeyType(xkb, info, &type))
1005     {
1006         info->errorCount++;
1007         return False;
1008     }
1009     return True;
1010 }
1011
1012 /**
1013  * Process an xkb_types section.
1014  *
1015  * @param file The parsed xkb_types section.
1016  * @param merge Merge Strategy (e.g. MergeOverride)
1017  * @param info Pointer to memory where the outcome will be stored.
1018  */
1019 static void
1020 HandleKeyTypesFile(XkbFile * file,
1021                    struct xkb_desc * xkb, unsigned merge, KeyTypesInfo * info)
1022 {
1023     ParseCommon *stmt;
1024
1025     info->name = _XkbDupString(file->name);
1026     stmt = file->defs;
1027     while (stmt)
1028     {
1029         switch (stmt->stmtType)
1030         {
1031         case StmtInclude:
1032             if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, xkb, info,
1033                                        HandleKeyTypesFile))
1034                 info->errorCount++;
1035             break;
1036         case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
1037             if (!HandleKeyTypeDef((KeyTypeDef *) stmt, xkb, merge, info))
1038                 info->errorCount++;
1039             break;
1040         case StmtVarDef:
1041             if (!HandleKeyTypeVar((VarDef *) stmt, xkb, info))
1042                 info->errorCount++;
1043             break;
1044         case StmtVModDef: /* virtual_modifiers NumLock, ... */
1045             if (!HandleVModDef((VModDef *) stmt, xkb, merge, &info->vmods))
1046                 info->errorCount++;
1047             break;
1048         case StmtKeyAliasDef:
1049             ERROR("Key type files may not include other declarations\n");
1050             ACTION("Ignoring definition of key alias\n");
1051             info->errorCount++;
1052             break;
1053         case StmtKeycodeDef:
1054             ERROR("Key type files may not include other declarations\n");
1055             ACTION("Ignoring definition of key name\n");
1056             info->errorCount++;
1057             break;
1058         case StmtInterpDef:
1059             ERROR("Key type files may not include other declarations\n");
1060             ACTION("Ignoring definition of symbol interpretation\n");
1061             info->errorCount++;
1062             break;
1063         default:
1064             WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
1065                   stmt->stmtType);
1066             break;
1067         }
1068         stmt = stmt->next;
1069         if (info->errorCount > 10)
1070         {
1071 #ifdef NOISY
1072             ERROR("Too many errors\n");
1073 #endif
1074             ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
1075             break;
1076         }
1077     }
1078     return;
1079 }
1080
1081 static Bool
1082 CopyDefToKeyType(struct xkb_desc * xkb, struct xkb_key_type * type, KeyTypeInfo * def)
1083 {
1084     register int i;
1085     PreserveInfo *pre;
1086
1087     for (pre = def->preserve; pre != NULL;
1088          pre = (PreserveInfo *) pre->defs.next)
1089     {
1090         struct xkb_kt_map_entry * match;
1091         struct xkb_kt_map_entry tmp;
1092         tmp.mods.real_mods = pre->indexMods;
1093         tmp.mods.vmods = pre->indexVMods;
1094         tmp.level = 0;
1095         AddMapEntry(xkb, def, &tmp, False, False);
1096         match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1097         if (!match)
1098         {
1099             WSGO("Couldn't find matching entry for preserve\n");
1100             ACTION("Aborting\n");
1101             return False;
1102         }
1103         pre->matchingMapIndex = match - def->entries;
1104     }
1105     type->mods.real_mods = def->mask;
1106     type->mods.vmods = def->vmask;
1107     type->num_levels = def->numLevels;
1108     type->map_count = def->nEntries;
1109     type->map = def->entries;
1110     if (def->preserve)
1111     {
1112         type->preserve = uTypedCalloc(type->map_count, struct xkb_mods);
1113         if (!type->preserve)
1114         {
1115             WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1116             ACTION("Preserve setting for type %s lost\n",
1117                     XkbcAtomText(def->name));
1118         }
1119         else
1120         {
1121             pre = def->preserve;
1122             for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
1123             {
1124                 int ndx = pre->matchingMapIndex;
1125                 type->preserve[ndx].mask = pre->preMods;
1126                 type->preserve[ndx].real_mods = pre->preMods;
1127                 type->preserve[ndx].vmods = pre->preVMods;
1128             }
1129         }
1130     }
1131     else
1132         type->preserve = NULL;
1133     type->name = (uint32_t) def->name;
1134     if (def->szNames > 0)
1135     {
1136         type->level_names = uTypedCalloc(def->numLevels, uint32_t);
1137
1138         /* assert def->szNames<=def->numLevels */
1139         for (i = 0; i < def->szNames; i++)
1140         {
1141             type->level_names[i] = (uint32_t) def->lvlNames[i];
1142         }
1143     }
1144     else
1145     {
1146         type->level_names = NULL;
1147     }
1148
1149     def->nEntries = def->szEntries = 0;
1150     def->entries = NULL;
1151     return XkbcComputeEffectiveMap(xkb, type, NULL);
1152 }
1153
1154 Bool
1155 CompileKeyTypes(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
1156 {
1157     KeyTypesInfo info;
1158
1159     InitKeyTypesInfo(&info, xkb, NULL);
1160     info.fileID = file->id;
1161     HandleKeyTypesFile(file, xkb, merge, &info);
1162
1163     if (info.errorCount == 0)
1164     {
1165         register int i;
1166         register KeyTypeInfo *def;
1167         register struct xkb_key_type *type, *next;
1168
1169         if (info.name != NULL)
1170         {
1171             if (XkbcAllocNames(xkb, XkbTypesNameMask, 0, 0) == Success)
1172                 xkb->names->types = xkb_intern_atom(info.name);
1173             else
1174             {
1175                 WSGO("Couldn't allocate space for types name\n");
1176                 ACTION("Name \"%s\" (from %s) NOT assigned\n",
1177                         scanFile, info.name);
1178             }
1179         }
1180         i = info.nTypes;
1181         if ((info.stdPresent & XkbOneLevelMask) == 0)
1182             i++;
1183         if ((info.stdPresent & XkbTwoLevelMask) == 0)
1184             i++;
1185         if ((info.stdPresent & XkbKeypadMask) == 0)
1186             i++;
1187         if ((info.stdPresent & XkbAlphabeticMask) == 0)
1188             i++;
1189         if (XkbcAllocClientMap(xkb, XkbKeyTypesMask, i) != Success)
1190         {
1191             FreeKeyTypesInfo(&info);
1192             WSGO("Couldn't allocate client map\n");
1193             return False;
1194         }
1195         xkb->map->num_types = i;
1196         if (XkbAllRequiredTypes & (~info.stdPresent))
1197         {
1198             unsigned missing, keypadVMod;
1199
1200             missing = XkbAllRequiredTypes & (~info.stdPresent);
1201             keypadVMod = FindKeypadVMod(xkb);
1202             if (XkbcInitCanonicalKeyTypes(xkb, missing, keypadVMod) != Success)
1203             {
1204                 FreeKeyTypesInfo(&info);
1205                 WSGO("Couldn't initialize canonical key types\n");
1206                 return False;
1207             }
1208             if (missing & XkbOneLevelMask)
1209                 xkb->map->types[XkbOneLevelIndex].name = tok_ONE_LEVEL;
1210             if (missing & XkbTwoLevelMask)
1211                 xkb->map->types[XkbTwoLevelIndex].name = tok_TWO_LEVEL;
1212             if (missing & XkbAlphabeticMask)
1213                 xkb->map->types[XkbAlphabeticIndex].name = tok_ALPHABETIC;
1214             if (missing & XkbKeypadMask)
1215                 xkb->map->types[XkbKeypadIndex].name = tok_KEYPAD;
1216         }
1217         next = &xkb->map->types[XkbLastRequiredType + 1];
1218         for (i = 0, def = info.types; i < info.nTypes; i++)
1219         {
1220             if (def->name == tok_ONE_LEVEL)
1221                 type = &xkb->map->types[XkbOneLevelIndex];
1222             else if (def->name == tok_TWO_LEVEL)
1223                 type = &xkb->map->types[XkbTwoLevelIndex];
1224             else if (def->name == tok_ALPHABETIC)
1225                 type = &xkb->map->types[XkbAlphabeticIndex];
1226             else if (def->name == tok_KEYPAD)
1227                 type = &xkb->map->types[XkbKeypadIndex];
1228             else
1229                 type = next++;
1230             DeleteLevel1MapEntries(def);
1231             if (!CopyDefToKeyType(xkb, type, def)) {
1232                 FreeKeyTypesInfo(&info);
1233                 return False;
1234             }
1235             def = (KeyTypeInfo *) def->defs.next;
1236         }
1237         FreeKeyTypesInfo(&info);
1238         return True;
1239     }
1240
1241     FreeKeyTypesInfo(&info);
1242     return False;
1243 }