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