Fix possible null dereferences
[profile/ivi/libxkbcommon.git] / src / xkbcomp / symbols.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 "parseutils.h"
32
33 #include <X11/keysym.h>
34 #include <stdlib.h>
35
36 #include "expr.h"
37 #include "vmod.h"
38 #include "action.h"
39 #include "keycodes.h"
40 #include "misc.h"
41 #include "alias.h"
42
43 extern uint32_t tok_ONE_LEVEL;
44 extern uint32_t tok_TWO_LEVEL;
45 extern uint32_t tok_KEYPAD;
46
47 /***====================================================================***/
48
49 #define RepeatYes       1
50 #define RepeatNo        0
51 #define RepeatUndefined ~((unsigned)0)
52
53 #define _Key_Syms       (1<<0)
54 #define _Key_Acts       (1<<1)
55 #define _Key_Repeat     (1<<2)
56 #define _Key_Behavior   (1<<3)
57 #define _Key_Type_Dflt  (1<<4)
58 #define _Key_Types      (1<<5)
59 #define _Key_GroupInfo  (1<<6)
60 #define _Key_VModMap    (1<<7)
61
62 typedef struct _KeyInfo
63 {
64     CommonInfo defs;
65     unsigned long name; /* the 4 chars of the key name, as long */
66     unsigned char groupInfo;
67     unsigned char typesDefined;
68     unsigned char symsDefined;
69     unsigned char actsDefined;
70     short numLevels[XkbNumKbdGroups];
71     uint32_t *syms[XkbNumKbdGroups];
72     union xkb_action *acts[XkbNumKbdGroups];
73     uint32_t types[XkbNumKbdGroups];
74     unsigned repeat;
75     struct xkb_behavior behavior;
76     unsigned short vmodmap;
77     unsigned long nameForOverlayKey;
78     unsigned long allowNone;
79     uint32_t dfltType;
80 } KeyInfo;
81
82 /**
83  * Init the given key info to sane values.
84  */
85 static void
86 InitKeyInfo(KeyInfo * info)
87 {
88     register int i;
89     static char dflt[4] = "*";
90
91     info->defs.defined = 0;
92     info->defs.fileID = 0;
93     info->defs.merge = MergeOverride;
94     info->defs.next = NULL;
95     info->name = KeyNameToLong(dflt);
96     info->groupInfo = 0;
97     info->typesDefined = info->symsDefined = info->actsDefined = 0;
98     for (i = 0; i < XkbNumKbdGroups; i++)
99     {
100         info->numLevels[i] = 0;
101         info->types[i] = None;
102         info->syms[i] = NULL;
103         info->acts[i] = NULL;
104     }
105     info->dfltType = None;
106     info->behavior.type = XkbKB_Default;
107     info->behavior.data = 0;
108     info->vmodmap = 0;
109     info->nameForOverlayKey = 0;
110     info->repeat = RepeatUndefined;
111     info->allowNone = 0;
112     return;
113 }
114
115 /**
116  * Free memory associated with this key info and reset to sane values.
117  */
118 static void
119 FreeKeyInfo(KeyInfo * info)
120 {
121     register int i;
122
123     info->defs.defined = 0;
124     info->defs.fileID = 0;
125     info->defs.merge = MergeOverride;
126     info->defs.next = NULL;
127     info->groupInfo = 0;
128     info->typesDefined = info->symsDefined = info->actsDefined = 0;
129     for (i = 0; i < XkbNumKbdGroups; i++)
130     {
131         info->numLevels[i] = 0;
132         info->types[i] = None;
133         if (info->syms[i] != NULL)
134             free(info->syms[i]);
135         info->syms[i] = NULL;
136         if (info->acts[i] != NULL)
137             free(info->acts[i]);
138         info->acts[i] = NULL;
139     }
140     info->dfltType = None;
141     info->behavior.type = XkbKB_Default;
142     info->behavior.data = 0;
143     info->vmodmap = 0;
144     info->nameForOverlayKey = 0;
145     info->repeat = RepeatUndefined;
146     info->allowNone = 0;
147     return;
148 }
149
150 /**
151  * Copy old into new, optionally reset old to 0.
152  * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
153  * newly allocated and new points to the new memory areas.
154  */
155 static Bool
156 CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld)
157 {
158     register int i;
159
160     *new = *old;
161     new->defs.next = NULL;
162     if (clearOld)
163     {
164         for (i = 0; i < XkbNumKbdGroups; i++)
165         {
166             old->numLevels[i] = 0;
167             old->syms[i] = NULL;
168             old->acts[i] = NULL;
169         }
170     }
171     else
172     {
173         int width;
174         for (i = 0; i < XkbNumKbdGroups; i++)
175         {
176             width = new->numLevels[i];
177             if (old->syms[i] != NULL)
178             {
179                 new->syms[i] = uTypedCalloc(width, uint32_t);
180                 if (!new->syms[i])
181                 {
182                     new->syms[i] = NULL;
183                     new->numLevels[i] = 0;
184                     return False;
185                 }
186                 memcpy((char *) new->syms[i], (char *) old->syms[i],
187                        width * sizeof(uint32_t));
188             }
189             if (old->acts[i] != NULL)
190             {
191                 new->acts[i] = uTypedCalloc(width, union xkb_action);
192                 if (!new->acts[i])
193                 {
194                     new->acts[i] = NULL;
195                     return False;
196                 }
197                 memcpy((char *) new->acts[i], (char *) old->acts[i],
198                        width * sizeof(union xkb_action));
199             }
200         }
201     }
202     return True;
203 }
204
205 /***====================================================================***/
206
207 typedef struct _ModMapEntry
208 {
209     CommonInfo defs;
210     Bool haveSymbol;
211     int modifier;
212     union
213     {
214         unsigned long keyName;
215         uint32_t keySym;
216     } u;
217 } ModMapEntry;
218
219 #define SYMBOLS_INIT_SIZE       110
220 #define SYMBOLS_CHUNK           20
221 typedef struct _SymbolsInfo
222 {
223     char *name;         /* e.g. pc+us+inet(evdev) */
224     int errorCount;
225     unsigned fileID;
226     unsigned merge;
227     unsigned explicit_group;
228     unsigned groupInfo;
229     unsigned szKeys;
230     unsigned nKeys;
231     KeyInfo *keys;
232     KeyInfo dflt;
233     VModInfo vmods;
234     ActionInfo *action;
235     uint32_t groupNames[XkbNumKbdGroups];
236
237     ModMapEntry *modMap;
238     AliasInfo *aliases;
239 } SymbolsInfo;
240
241 static void
242 InitSymbolsInfo(SymbolsInfo * info, struct xkb_desc * xkb)
243 {
244     register int i;
245
246     tok_ONE_LEVEL = xkb_intern_atom("ONE_LEVEL");
247     tok_TWO_LEVEL = xkb_intern_atom("TWO_LEVEL");
248     tok_KEYPAD = xkb_intern_atom("KEYPAD");
249     info->name = NULL;
250     info->explicit_group = 0;
251     info->errorCount = 0;
252     info->fileID = 0;
253     info->merge = MergeOverride;
254     info->groupInfo = 0;
255     info->szKeys = SYMBOLS_INIT_SIZE;
256     info->nKeys = 0;
257     info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo);
258     info->modMap = NULL;
259     for (i = 0; i < XkbNumKbdGroups; i++)
260         info->groupNames[i] = None;
261     InitKeyInfo(&info->dflt);
262     InitVModInfo(&info->vmods, xkb);
263     info->action = NULL;
264     info->aliases = NULL;
265     return;
266 }
267
268 static void
269 FreeSymbolsInfo(SymbolsInfo * info)
270 {
271     register int i;
272
273     if (info->name)
274         free(info->name);
275     info->name = NULL;
276     if (info->keys)
277     {
278         for (i = 0; i < info->nKeys; i++)
279         {
280             FreeKeyInfo(&info->keys[i]);
281         }
282         free(info->keys);
283         info->keys = NULL;
284     }
285     if (info->modMap)
286     {
287         ClearCommonInfo(&info->modMap->defs);
288         info->modMap = NULL;
289     }
290     if (info->aliases)
291     {
292         ClearAliases(&info->aliases);
293         info->aliases = NULL;
294     }
295     bzero((char *) info, sizeof(SymbolsInfo));
296     return;
297 }
298
299 static Bool
300 ResizeKeyGroup(KeyInfo * key,
301                unsigned group, unsigned atLeastSize, Bool forceActions)
302 {
303     Bool tooSmall;
304     unsigned newWidth;
305
306     tooSmall = (key->numLevels[group] < atLeastSize);
307     if (tooSmall)
308         newWidth = atLeastSize;
309     else
310         newWidth = key->numLevels[group];
311
312     if ((key->syms[group] == NULL) || tooSmall)
313     {
314         key->syms[group] = uTypedRecalloc(key->syms[group],
315                                           key->numLevels[group], newWidth,
316                                           uint32_t);
317         if (!key->syms[group])
318             return False;
319     }
320     if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) ||
321         (tooSmall && (key->acts[group] != NULL)))
322     {
323         key->acts[group] = uTypedRecalloc(key->acts[group],
324                                           key->numLevels[group], newWidth,
325                                           union xkb_action);
326         if (!key->acts[group])
327             return False;
328     }
329     key->numLevels[group] = newWidth;
330     return True;
331 }
332
333 static Bool
334 MergeKeyGroups(SymbolsInfo * info,
335                KeyInfo * into, KeyInfo * from, unsigned group)
336 {
337     uint32_t *resultSyms;
338     union xkb_action *resultActs;
339     int resultWidth;
340     register int i;
341     Bool report, clobber;
342
343     clobber = (from->defs.merge != MergeAugment);
344     report = (warningLevel > 9) ||
345         ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
346     if (into->numLevels[group] >= from->numLevels[group])
347     {
348         resultSyms = into->syms[group];
349         resultActs = into->acts[group];
350         resultWidth = into->numLevels[group];
351     }
352     else
353     {
354         resultSyms = from->syms[group];
355         resultActs = from->acts[group];
356         resultWidth = from->numLevels[group];
357     }
358     if (resultSyms == NULL)
359     {
360         resultSyms = uTypedCalloc(resultWidth, uint32_t);
361         if (!resultSyms)
362         {
363             WSGO("Could not allocate symbols for group merge\n");
364             ACTION("Group %d of key %s not merged\n", group,
365                     longText(into->name));
366             return False;
367         }
368     }
369     if ((resultActs == NULL) && (into->acts[group] || from->acts[group]))
370     {
371         resultActs = uTypedCalloc(resultWidth, union xkb_action);
372         if (!resultActs)
373         {
374             WSGO("Could not allocate actions for group merge\n");
375             ACTION("Group %d of key %s not merged\n", group,
376                     longText(into->name));
377             return False;
378         }
379     }
380     for (i = 0; i < resultWidth; i++)
381     {
382         uint32_t fromSym, toSym;
383         if (from->syms[group] && (i < from->numLevels[group]))
384             fromSym = from->syms[group][i];
385         else
386             fromSym = NoSymbol;
387         if (into->syms[group] && (i < into->numLevels[group]))
388             toSym = into->syms[group][i];
389         else
390             toSym = NoSymbol;
391         if ((fromSym == NoSymbol) || (fromSym == toSym))
392             resultSyms[i] = toSym;
393         else if (toSym == NoSymbol)
394             resultSyms[i] = fromSym;
395         else
396         {
397             uint32_t use, ignore;
398             if (clobber)
399             {
400                 use = fromSym;
401                 ignore = toSym;
402             }
403             else
404             {
405                 use = toSym;
406                 ignore = fromSym;
407             }
408             if (report)
409             {
410                 WARN
411                     ("Multiple symbols for level %d/group %d on key %s\n",
412                      i + 1, group + 1, longText(into->name));
413                 ACTION("Using %s, ignoring %s\n",
414                         XkbcKeysymText(use), XkbcKeysymText(ignore));
415             }
416             resultSyms[i] = use;
417         }
418         if (resultActs != NULL)
419         {
420             union xkb_action *fromAct, *toAct;
421             fromAct = (from->acts[group] ? &from->acts[group][i] : NULL);
422             toAct = (into->acts[group] ? &into->acts[group][i] : NULL);
423             if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
424                 && (toAct != NULL))
425             {
426                 resultActs[i] = *toAct;
427             }
428             else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
429                      && (fromAct != NULL))
430             {
431                 resultActs[i] = *fromAct;
432             }
433             else
434             {
435                 union xkb_action *use, *ignore;
436                 if (clobber)
437                 {
438                     use = fromAct;
439                     ignore = toAct;
440                 }
441                 else
442                 {
443                     use = toAct;
444                     ignore = fromAct;
445                 }
446                 if (report)
447                 {
448                     WARN
449                         ("Multiple actions for level %d/group %d on key %s\n",
450                          i + 1, group + 1, longText(into->name));
451                     ACTION("Using %s, ignoring %s\n",
452                             XkbcActionTypeText(use->type),
453                             XkbcActionTypeText(ignore->type));
454                 }
455                 if (use)
456                     resultActs[i] = *use;
457             }
458         }
459     }
460     if ((into->syms[group] != NULL) && (resultSyms != into->syms[group]))
461         free(into->syms[group]);
462     if ((from->syms[group] != NULL) && (resultSyms != from->syms[group]))
463         free(from->syms[group]);
464     if ((into->acts[group] != NULL) && (resultActs != into->acts[group]))
465         free(into->acts[group]);
466     if ((from->acts[group] != NULL) && (resultActs != from->acts[group]))
467         free(from->acts[group]);
468     into->numLevels[group] = resultWidth;
469     into->syms[group] = resultSyms;
470     from->syms[group] = NULL;
471     into->acts[group] = resultActs;
472     from->acts[group] = NULL;
473     into->symsDefined |= (1 << group);
474     from->symsDefined &= ~(1 << group);
475     into->actsDefined |= (1 << group);
476     from->actsDefined &= ~(1 << group);
477     return True;
478 }
479
480 static Bool
481 MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from)
482 {
483     register int i;
484     unsigned collide = 0;
485     Bool report;
486
487     if (from->defs.merge == MergeReplace)
488     {
489         for (i = 0; i < XkbNumKbdGroups; i++)
490         {
491             if (into->numLevels[i] != 0)
492             {
493                 if (into->syms[i])
494                     free(into->syms[i]);
495                 if (into->acts[i])
496                     free(into->acts[i]);
497             }
498         }
499         *into = *from;
500         bzero(from, sizeof(KeyInfo));
501         return True;
502     }
503     report = ((warningLevel > 9) ||
504               ((into->defs.fileID == from->defs.fileID)
505                && (warningLevel > 0)));
506     for (i = 0; i < XkbNumKbdGroups; i++)
507     {
508         if (from->numLevels[i] > 0)
509         {
510             if (into->numLevels[i] == 0)
511             {
512                 into->numLevels[i] = from->numLevels[i];
513                 into->syms[i] = from->syms[i];
514                 into->acts[i] = from->acts[i];
515                 into->symsDefined |= (1 << i);
516                 from->syms[i] = NULL;
517                 from->acts[i] = NULL;
518                 from->numLevels[i] = 0;
519                 from->symsDefined &= ~(1 << i);
520                 if (into->syms[i])
521                     into->defs.defined |= _Key_Syms;
522                 if (into->acts[i])
523                     into->defs.defined |= _Key_Acts;
524             }
525             else
526             {
527                 if (report)
528                 {
529                     if (into->syms[i])
530                         collide |= _Key_Syms;
531                     if (into->acts[i])
532                         collide |= _Key_Acts;
533                 }
534                 MergeKeyGroups(info, into, from, (unsigned) i);
535             }
536         }
537         if (from->types[i] != None)
538         {
539             if ((into->types[i] != None) && (report) &&
540                 (into->types[i] != from->types[i]))
541             {
542                 uint32_t use, ignore;
543                 collide |= _Key_Types;
544                 if (from->defs.merge != MergeAugment)
545                 {
546                     use = from->types[i];
547                     ignore = into->types[i];
548                 }
549                 else
550                 {
551                     use = into->types[i];
552                     ignore = from->types[i];
553                 }
554                 WARN
555                     ("Multiple definitions for group %d type of key %s\n",
556                      i, longText(into->name));
557                 ACTION("Using %s, ignoring %s\n",
558                         XkbcAtomText(use),
559                         XkbcAtomText(ignore));
560             }
561             if ((from->defs.merge != MergeAugment)
562                 || (into->types[i] == None))
563             {
564                 into->types[i] = from->types[i];
565             }
566         }
567     }
568     if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
569     {
570         into->behavior = from->behavior;
571         into->nameForOverlayKey = from->nameForOverlayKey;
572         into->defs.defined |= _Key_Behavior;
573     }
574     if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
575     {
576         into->vmodmap = from->vmodmap;
577         into->defs.defined |= _Key_VModMap;
578     }
579     if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
580     {
581         into->repeat = from->repeat;
582         into->defs.defined |= _Key_Repeat;
583     }
584     if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
585     {
586         into->dfltType = from->dfltType;
587         into->defs.defined |= _Key_Type_Dflt;
588     }
589     if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
590     {
591         into->groupInfo = from->groupInfo;
592         into->defs.defined |= _Key_GroupInfo;
593     }
594     if (collide)
595     {
596         WARN("Symbol map for key %s redefined\n",
597               longText(into->name));
598         ACTION("Using %s definition for conflicting fields\n",
599                 (from->defs.merge == MergeAugment ? "first" : "last"));
600     }
601     return True;
602 }
603
604 static Bool
605 AddKeySymbols(SymbolsInfo * info, KeyInfo * key, struct xkb_desc * xkb)
606 {
607     register int i;
608     unsigned long real_name;
609
610     for (i = 0; i < info->nKeys; i++)
611     {
612         if (info->keys[i].name == key->name)
613             return MergeKeys(info, &info->keys[i], key);
614     }
615     if (FindKeyNameForAlias(xkb, key->name, &real_name))
616     {
617         for (i = 0; i < info->nKeys; i++)
618         {
619             if (info->keys[i].name == real_name)
620                 return MergeKeys(info, &info->keys[i], key);
621         }
622     }
623     if (info->nKeys >= info->szKeys)
624     {
625         info->szKeys += SYMBOLS_CHUNK;
626         info->keys =
627             uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo);
628         if (!info->keys)
629         {
630             WSGO("Could not allocate key symbols descriptions\n");
631             ACTION("Some key symbols definitions may be lost\n");
632             return False;
633         }
634     }
635     return CopyKeyInfo(key, &info->keys[info->nKeys++], True);
636 }
637
638 static Bool
639 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
640 {
641     ModMapEntry *mm;
642     Bool clobber;
643
644     clobber = (new->defs.merge != MergeAugment);
645     for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
646     {
647         if (new->haveSymbol && mm->haveSymbol
648             && (new->u.keySym == mm->u.keySym))
649         {
650             unsigned use, ignore;
651             if (mm->modifier != new->modifier)
652             {
653                 if (clobber)
654                 {
655                     use = new->modifier;
656                     ignore = mm->modifier;
657                 }
658                 else
659                 {
660                     use = mm->modifier;
661                     ignore = new->modifier;
662                 }
663                 ERROR
664                     ("%s added to symbol map for multiple modifiers\n",
665                      XkbcKeysymText(new->u.keySym));
666                 ACTION("Using %s, ignoring %s.\n",
667                         XkbcModIndexText(use),
668                         XkbcModIndexText(ignore));
669                 mm->modifier = use;
670             }
671             return True;
672         }
673         if ((!new->haveSymbol) && (!mm->haveSymbol) &&
674             (new->u.keyName == mm->u.keyName))
675         {
676             unsigned use, ignore;
677             if (mm->modifier != new->modifier)
678             {
679                 if (clobber)
680                 {
681                     use = new->modifier;
682                     ignore = mm->modifier;
683                 }
684                 else
685                 {
686                     use = mm->modifier;
687                     ignore = new->modifier;
688                 }
689                 ERROR("Key %s added to map for multiple modifiers\n",
690                        longText(new->u.keyName));
691                 ACTION("Using %s, ignoring %s.\n",
692                         XkbcModIndexText(use),
693                         XkbcModIndexText(ignore));
694                 mm->modifier = use;
695             }
696             return True;
697         }
698     }
699     mm = uTypedAlloc(ModMapEntry);
700     if (mm == NULL)
701     {
702         WSGO("Could not allocate modifier map entry\n");
703         ACTION("Modifier map for %s will be incomplete\n",
704                 XkbcModIndexText(new->modifier));
705         return False;
706     }
707     *mm = *new;
708     mm->defs.next = &info->modMap->defs;
709     info->modMap = mm;
710     return True;
711 }
712
713 /***====================================================================***/
714
715 static void
716 MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from,
717                      unsigned merge, struct xkb_desc * xkb)
718 {
719     register int i;
720     KeyInfo *key;
721
722     if (from->errorCount > 0)
723     {
724         into->errorCount += from->errorCount;
725         return;
726     }
727     if (into->name == NULL)
728     {
729         into->name = from->name;
730         from->name = NULL;
731     }
732     for (i = 0; i < XkbNumKbdGroups; i++)
733     {
734         if (from->groupNames[i] != None)
735         {
736             if ((merge != MergeAugment) || (into->groupNames[i] == None))
737                 into->groupNames[i] = from->groupNames[i];
738         }
739     }
740     for (i = 0, key = from->keys; i < from->nKeys; i++, key++)
741     {
742         if (merge != MergeDefault)
743             key->defs.merge = merge;
744         if (!AddKeySymbols(into, key, xkb))
745             into->errorCount++;
746     }
747     if (from->modMap != NULL)
748     {
749         ModMapEntry *mm, *next;
750         for (mm = from->modMap; mm != NULL; mm = next)
751         {
752             if (merge != MergeDefault)
753                 mm->defs.merge = merge;
754             if (!AddModMapEntry(into, mm))
755                 into->errorCount++;
756             next = (ModMapEntry *) mm->defs.next;
757             free(mm);
758         }
759         from->modMap = NULL;
760     }
761     if (!MergeAliases(&into->aliases, &from->aliases, merge))
762         into->errorCount++;
763     return;
764 }
765
766 typedef void (*FileHandler) (XkbFile * /* rtrn */ ,
767                              struct xkb_desc * /* xkb */ ,
768                              unsigned /* merge */ ,
769                              SymbolsInfo *      /* included */
770     );
771
772 static Bool
773 HandleIncludeSymbols(IncludeStmt * stmt,
774                      struct xkb_desc * xkb, SymbolsInfo * info, FileHandler hndlr)
775 {
776     unsigned newMerge;
777     XkbFile *rtrn;
778     SymbolsInfo included;
779     Bool haveSelf;
780
781     haveSelf = False;
782     if ((stmt->file == NULL) && (stmt->map == NULL))
783     {
784         haveSelf = True;
785         included = *info;
786         bzero(info, sizeof(SymbolsInfo));
787     }
788     else if (ProcessIncludeFile(stmt, XkmSymbolsIndex, &rtrn, &newMerge))
789     {
790         InitSymbolsInfo(&included, xkb);
791         included.fileID = included.dflt.defs.fileID = rtrn->id;
792         included.merge = included.dflt.defs.merge = MergeOverride;
793         if (stmt->modifier)
794         {
795             included.explicit_group = atoi(stmt->modifier) - 1;
796         }
797         else
798         {
799             included.explicit_group = info->explicit_group;
800         }
801         (*hndlr) (rtrn, xkb, MergeOverride, &included);
802         if (stmt->stmt != NULL)
803         {
804             if (included.name != NULL)
805                 free(included.name);
806             included.name = stmt->stmt;
807             stmt->stmt = NULL;
808         }
809     }
810     else
811     {
812         info->errorCount += 10;
813         return False;
814     }
815     if ((stmt->next != NULL) && (included.errorCount < 1))
816     {
817         IncludeStmt *next;
818         unsigned op;
819         SymbolsInfo next_incl;
820
821         for (next = stmt->next; next != NULL; next = next->next)
822         {
823             if ((next->file == NULL) && (next->map == NULL))
824             {
825                 haveSelf = True;
826                 MergeIncludedSymbols(&included, info, next->merge, xkb);
827                 FreeSymbolsInfo(info);
828             }
829             else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op))
830             {
831                 InitSymbolsInfo(&next_incl, xkb);
832                 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
833                 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride;
834                 if (next->modifier)
835                 {
836                     next_incl.explicit_group = atoi(next->modifier) - 1;
837                 }
838                 else
839                 {
840                     next_incl.explicit_group = info->explicit_group;
841                 }
842                 (*hndlr) (rtrn, xkb, MergeOverride, &next_incl);
843                 MergeIncludedSymbols(&included, &next_incl, op, xkb);
844                 FreeSymbolsInfo(&next_incl);
845             }
846             else
847             {
848                 info->errorCount += 10;
849                 return False;
850             }
851         }
852     }
853     if (haveSelf)
854         *info = included;
855     else
856     {
857         MergeIncludedSymbols(info, &included, newMerge, xkb);
858         FreeSymbolsInfo(&included);
859     }
860     return (info->errorCount == 0);
861 }
862
863 #define SYMBOLS 1
864 #define ACTIONS 2
865
866 static Bool
867 GetGroupIndex(KeyInfo * key,
868               ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
869 {
870     const char *name;
871     ExprResult tmp;
872
873     if (what == SYMBOLS)
874         name = "symbols";
875     else
876         name = "actions";
877
878     if (arrayNdx == NULL)
879     {
880         register int i;
881         unsigned defined;
882         if (what == SYMBOLS)
883             defined = key->symsDefined;
884         else
885             defined = key->actsDefined;
886
887         for (i = 0; i < XkbNumKbdGroups; i++)
888         {
889             if ((defined & (1 << i)) == 0)
890             {
891                 *ndx_rtrn = i;
892                 return True;
893             }
894         }
895         ERROR("Too many groups of %s for key %s (max %d)\n", name,
896                longText(key->name), XkbNumKbdGroups + 1);
897         ACTION("Ignoring %s defined for extra groups\n", name);
898         return False;
899     }
900     if (!ExprResolveGroup(arrayNdx, &tmp))
901     {
902         ERROR("Illegal group index for %s of key %s\n", name,
903                longText(key->name));
904         ACTION("Definition with non-integer array index ignored\n");
905         return False;
906     }
907     *ndx_rtrn = tmp.uval - 1;
908     return True;
909 }
910
911 static Bool
912 AddSymbolsToKey(KeyInfo * key,
913                 struct xkb_desc * xkb,
914                 char *field,
915                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
916 {
917     unsigned ndx, nSyms;
918     int i;
919
920     if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx))
921         return False;
922     if (value == NULL)
923     {
924         key->symsDefined |= (1 << ndx);
925         return True;
926     }
927     if (value->op != ExprKeysymList)
928     {
929         ERROR("Expected a list of symbols, found %s\n",
930                exprOpText(value->op));
931         ACTION("Ignoring symbols for group %d of %s\n", ndx,
932                 longText(key->name));
933         return False;
934     }
935     if (key->syms[ndx] != NULL)
936     {
937         WSGO("Symbols for key %s, group %d already defined\n",
938               longText(key->name), ndx);
939         return False;
940     }
941     nSyms = value->value.list.nSyms;
942     if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
943         (!ResizeKeyGroup(key, ndx, nSyms, False)))
944     {
945         WSGO("Could not resize group %d of key %s\n", ndx,
946               longText(key->name));
947         ACTION("Symbols lost\n");
948         return False;
949     }
950     key->symsDefined |= (1 << ndx);
951     for (i = 0; i < nSyms; i++) {
952         if (!LookupKeysym(value->value.list.syms[i], &key->syms[ndx][i])) {
953             WSGO("Could not resolve keysym %s\n", value->value.list.syms[i]);
954             key->syms[ndx][i] = NoSymbol;
955         }
956     }
957     for (i = key->numLevels[ndx] - 1;
958          (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--)
959     {
960         key->numLevels[ndx]--;
961     }
962     return True;
963 }
964
965 static Bool
966 AddActionsToKey(KeyInfo * key,
967                 struct xkb_desc * xkb,
968                 char *field,
969                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
970 {
971     register int i;
972     unsigned ndx, nActs;
973     ExprDef *act;
974     struct xkb_any_action *toAct;
975
976     if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx))
977         return False;
978
979     if (value == NULL)
980     {
981         key->actsDefined |= (1 << ndx);
982         return True;
983     }
984     if (value->op != ExprActionList)
985     {
986         WSGO("Bad expression type (%d) for action list value\n", value->op);
987         ACTION("Ignoring actions for group %d of %s\n", ndx,
988                 longText(key->name));
989         return False;
990     }
991     if (key->acts[ndx] != NULL)
992     {
993         WSGO("Actions for key %s, group %d already defined\n",
994               longText(key->name), ndx);
995         return False;
996     }
997     for (nActs = 0, act = value->value.child; act != NULL; nActs++)
998     {
999         act = (ExprDef *) act->common.next;
1000     }
1001     if (nActs < 1)
1002     {
1003         WSGO("Action list but not actions in AddActionsToKey\n");
1004         return False;
1005     }
1006     if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1007         (!ResizeKeyGroup(key, ndx, nActs, True)))
1008     {
1009         WSGO("Could not resize group %d of key %s\n", ndx,
1010               longText(key->name));
1011         ACTION("Actions lost\n");
1012         return False;
1013     }
1014     key->actsDefined |= (1 << ndx);
1015
1016     toAct = (struct xkb_any_action *) key->acts[ndx];
1017     act = value->value.child;
1018     for (i = 0; i < nActs; i++, toAct++)
1019     {
1020         if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action))
1021         {
1022             ERROR("Illegal action definition for %s\n",
1023                    longText(key->name));
1024             ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1025         }
1026         act = (ExprDef *) act->common.next;
1027     }
1028     return True;
1029 }
1030
1031 static int
1032 SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value)
1033 {
1034     ExprResult tmp;
1035     unsigned radio_groups = 0;
1036
1037     if (arrayNdx == NULL)
1038     {
1039         radio_groups = XkbAllRadioGroupsMask;
1040     }
1041     else
1042     {
1043         if (!ExprResolveRadioGroup(arrayNdx, &tmp))
1044         {
1045             ERROR("Illegal index in group name definition\n");
1046             ACTION("Definition with non-integer array index ignored\n");
1047             return False;
1048         }
1049         if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1050         {
1051             ERROR("Illegal radio group specified (must be 1..%d)\n",
1052                    XkbMaxRadioGroups + 1);
1053             ACTION("Value of \"allow none\" for group %d ignored\n",
1054                     tmp.uval);
1055             return False;
1056         }
1057         radio_groups |= (1 << (tmp.uval - 1));
1058     }
1059     if (!ExprResolveBoolean(value, &tmp))
1060     {
1061         ERROR("Illegal \"allow none\" value for %s\n",
1062                longText(key->name));
1063         ACTION("Non-boolean value ignored\n");
1064         return False;
1065     }
1066     if (tmp.uval)
1067         key->allowNone |= radio_groups;
1068     else
1069         key->allowNone &= ~radio_groups;
1070     return True;
1071 }
1072
1073
1074 static LookupEntry lockingEntries[] = {
1075     {"true", XkbKB_Lock},
1076     {"yes", XkbKB_Lock},
1077     {"on", XkbKB_Lock},
1078     {"false", XkbKB_Default},
1079     {"no", XkbKB_Default},
1080     {"off", XkbKB_Default},
1081     {"permanent", XkbKB_Lock | XkbKB_Permanent},
1082     {NULL, 0}
1083 };
1084
1085 static LookupEntry repeatEntries[] = {
1086     {"true", RepeatYes},
1087     {"yes", RepeatYes},
1088     {"on", RepeatYes},
1089     {"false", RepeatNo},
1090     {"no", RepeatNo},
1091     {"off", RepeatNo},
1092     {"default", RepeatUndefined},
1093     {NULL, 0}
1094 };
1095
1096 static Bool
1097 SetSymbolsField(KeyInfo * key,
1098                 struct xkb_desc * xkb,
1099                 char *field,
1100                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1101 {
1102     Bool ok = True;
1103     ExprResult tmp;
1104
1105     if (uStrCaseCmp(field, "type") == 0)
1106     {
1107         ExprResult ndx;
1108         if ((!ExprResolveString(value, &tmp))
1109             && (warningLevel > 0))
1110         {
1111             WARN("The type field of a key symbol map must be a string\n");
1112             ACTION("Ignoring illegal type definition\n");
1113         }
1114         if (arrayNdx == NULL)
1115         {
1116             key->dfltType = xkb_intern_atom(tmp.str);
1117             key->defs.defined |= _Key_Type_Dflt;
1118         }
1119         else if (!ExprResolveGroup(arrayNdx, &ndx))
1120         {
1121             ERROR("Illegal group index for type of key %s\n",
1122                    longText(key->name));
1123             ACTION("Definition with non-integer array index ignored\n");
1124             free(tmp.str);
1125             return False;
1126         }
1127         else
1128         {
1129             key->types[ndx.uval - 1] = xkb_intern_atom(tmp.str);
1130             key->typesDefined |= (1 << (ndx.uval - 1));
1131         }
1132         free(tmp.str);
1133     }
1134     else if (uStrCaseCmp(field, "symbols") == 0)
1135         return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1136     else if (uStrCaseCmp(field, "actions") == 0)
1137         return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1138     else if ((uStrCaseCmp(field, "vmods") == 0) ||
1139              (uStrCaseCmp(field, "virtualmods") == 0) ||
1140              (uStrCaseCmp(field, "virtualmodifiers") == 0))
1141     {
1142         ok = ExprResolveVModMask(value, &tmp, xkb);
1143         if (ok)
1144         {
1145             key->vmodmap = (tmp.uval >> 8);
1146             key->defs.defined |= _Key_VModMap;
1147         }
1148         else
1149         {
1150             ERROR("Expected a virtual modifier mask, found %s\n",
1151                    exprOpText(value->op));
1152             ACTION("Ignoring virtual modifiers definition for key %s\n",
1153                     longText(key->name));
1154         }
1155     }
1156     else if ((uStrCaseCmp(field, "locking") == 0)
1157              || (uStrCaseCmp(field, "lock") == 0)
1158              || (uStrCaseCmp(field, "locks") == 0))
1159     {
1160         ok = ExprResolveEnum(value, &tmp, lockingEntries);
1161         if (ok)
1162             key->behavior.type = tmp.uval;
1163         key->defs.defined |= _Key_Behavior;
1164     }
1165     else if ((uStrCaseCmp(field, "radiogroup") == 0) ||
1166              (uStrCaseCmp(field, "permanentradiogroup") == 0))
1167     {
1168         Bool permanent = False;
1169         if (uStrCaseCmp(field, "permanentradiogroup") == 0)
1170             permanent = True;
1171         if (ExprResolveString(value, &tmp)) {
1172             ok = (strcmp(tmp.str, "none") == 0);
1173             free(tmp.str);
1174             if (ok)
1175                 tmp.uval = 0;
1176         }
1177         else {
1178             ok = ExprResolveInteger(value, &tmp);
1179         }
1180         if (!ok)
1181         {
1182             ERROR("Illegal radio group specification for %s\n",
1183                   longText(key->name));
1184             ACTION("Non-integer radio group ignored\n");
1185             return False;
1186         }
1187         if (tmp.uval == 0)
1188         {
1189             key->behavior.type = XkbKB_Default;
1190             key->behavior.data = 0;
1191             return ok;
1192         }
1193         if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1194         {
1195             ERROR
1196                 ("Radio group specification for %s out of range (1..32)\n",
1197                  longText(key->name));
1198             ACTION("Illegal radio group %d ignored\n", tmp.uval);
1199             return False;
1200         }
1201         key->behavior.type =
1202             XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0);
1203         key->behavior.data = tmp.uval - 1;
1204         if (key->allowNone & (1 << (tmp.uval - 1)))
1205             key->behavior.data |= XkbKB_RGAllowNone;
1206         key->defs.defined |= _Key_Behavior;
1207     }
1208     else if (uStrCaseEqual(field, "allownone"))
1209     {
1210         ok = SetAllowNone(key, arrayNdx, value);
1211     }
1212     else if (uStrCasePrefix("overlay", field) ||
1213              uStrCasePrefix("permanentoverlay", field))
1214     {
1215         Bool permanent = False;
1216         char *which;
1217         int overlayNdx;
1218         if (uStrCasePrefix("permanent", field))
1219         {
1220             permanent = True;
1221             which = &field[sizeof("permanentoverlay") - 1];
1222         }
1223         else
1224         {
1225             which = &field[sizeof("overlay") - 1];
1226         }
1227         if (sscanf(which, "%d", &overlayNdx) == 1)
1228         {
1229             if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0))
1230             {
1231                 ERROR("Illegal overlay %d specified for %s\n",
1232                        overlayNdx, longText(key->name));
1233                 ACTION("Ignored\n");
1234                 return False;
1235             }
1236         }
1237         else if (*which == '\0')
1238             overlayNdx = 1;
1239         else if (warningLevel > 0)
1240         {
1241             ERROR("Illegal overlay \"%s\" specified for %s\n",
1242                    which, longText(key->name));
1243             ACTION("Ignored\n");
1244             return False;
1245         }
1246         ok = ExprResolveKeyName(value, &tmp);
1247         if (!ok)
1248         {
1249             ERROR("Illegal overlay key specification for %s\n",
1250                    longText(key->name));
1251             ACTION("Overlay key must be specified by name\n");
1252             return False;
1253         }
1254         if (overlayNdx == 1)
1255             key->behavior.type = XkbKB_Overlay1;
1256         else
1257             key->behavior.type = XkbKB_Overlay2;
1258         if (permanent)
1259             key->behavior.type |= XkbKB_Permanent;
1260
1261         key->behavior.data = 0;
1262         key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name);
1263         key->defs.defined |= _Key_Behavior;
1264     }
1265     else if ((uStrCaseCmp(field, "repeating") == 0) ||
1266              (uStrCaseCmp(field, "repeats") == 0) ||
1267              (uStrCaseCmp(field, "repeat") == 0))
1268     {
1269         ok = ExprResolveEnum(value, &tmp, repeatEntries);
1270         if (!ok)
1271         {
1272             ERROR("Illegal repeat setting for %s\n",
1273                    longText(key->name));
1274             ACTION("Non-boolean repeat setting ignored\n");
1275             return False;
1276         }
1277         key->repeat = tmp.uval;
1278         key->defs.defined |= _Key_Repeat;
1279     }
1280     else if ((uStrCaseCmp(field, "groupswrap") == 0) ||
1281              (uStrCaseCmp(field, "wrapgroups") == 0))
1282     {
1283         ok = ExprResolveBoolean(value, &tmp);
1284         if (!ok)
1285         {
1286             ERROR("Illegal groupsWrap setting for %s\n",
1287                    longText(key->name));
1288             ACTION("Non-boolean value ignored\n");
1289             return False;
1290         }
1291         if (tmp.uval)
1292             key->groupInfo = XkbWrapIntoRange;
1293         else
1294             key->groupInfo = XkbClampIntoRange;
1295         key->defs.defined |= _Key_GroupInfo;
1296     }
1297     else if ((uStrCaseCmp(field, "groupsclamp") == 0) ||
1298              (uStrCaseCmp(field, "clampgroups") == 0))
1299     {
1300         ok = ExprResolveBoolean(value, &tmp);
1301         if (!ok)
1302         {
1303             ERROR("Illegal groupsClamp setting for %s\n",
1304                    longText(key->name));
1305             ACTION("Non-boolean value ignored\n");
1306             return False;
1307         }
1308         if (tmp.uval)
1309             key->groupInfo = XkbClampIntoRange;
1310         else
1311             key->groupInfo = XkbWrapIntoRange;
1312         key->defs.defined |= _Key_GroupInfo;
1313     }
1314     else if ((uStrCaseCmp(field, "groupsredirect") == 0) ||
1315              (uStrCaseCmp(field, "redirectgroups") == 0))
1316     {
1317         if (!ExprResolveGroup(value, &tmp))
1318         {
1319             ERROR("Illegal group index for redirect of key %s\n",
1320                    longText(key->name));
1321             ACTION("Definition with non-integer group ignored\n");
1322             return False;
1323         }
1324         key->groupInfo =
1325             XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1326         key->defs.defined |= _Key_GroupInfo;
1327     }
1328     else
1329     {
1330         ERROR("Unknown field %s in a symbol interpretation\n", field);
1331         ACTION("Definition ignored\n");
1332         ok = False;
1333     }
1334     return ok;
1335 }
1336
1337 static int
1338 SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1339 {
1340     ExprResult tmp, name;
1341
1342     if ((arrayNdx == NULL) && (warningLevel > 0))
1343     {
1344         WARN("You must specify an index when specifying a group name\n");
1345         ACTION("Group name definition without array subscript ignored\n");
1346         return False;
1347     }
1348     if (!ExprResolveGroup(arrayNdx, &tmp))
1349     {
1350         ERROR("Illegal index in group name definition\n");
1351         ACTION("Definition with non-integer array index ignored\n");
1352         return False;
1353     }
1354     if (!ExprResolveString(value, &name))
1355     {
1356         ERROR("Group name must be a string\n");
1357         ACTION("Illegal name for group %d ignored\n", tmp.uval);
1358         return False;
1359     }
1360     info->groupNames[tmp.uval - 1 + info->explicit_group] =
1361         xkb_intern_atom(name.str);
1362     free(name.str);
1363
1364     return True;
1365 }
1366
1367 static int
1368 HandleSymbolsVar(VarDef * stmt, struct xkb_desc * xkb, SymbolsInfo * info)
1369 {
1370     ExprResult elem, field, tmp;
1371     ExprDef *arrayNdx;
1372     Bool ret;
1373
1374     if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1375         return 0;               /* internal error, already reported */
1376     if (elem.str && (uStrCaseCmp(elem.str, "key") == 0))
1377     {
1378         ret = SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1379                               stmt->value, info);
1380     }
1381     else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) ||
1382                                     (uStrCaseCmp(field.str, "groupname") ==
1383                                      0)))
1384     {
1385         ret = SetGroupName(info, arrayNdx, stmt->value);
1386     }
1387     else if ((elem.str == NULL)
1388              && ((uStrCaseCmp(field.str, "groupswrap") == 0)
1389                  || (uStrCaseCmp(field.str, "wrapgroups") == 0)))
1390     {
1391         if (!ExprResolveBoolean(stmt->value, &tmp))
1392         {
1393             ERROR("Illegal setting for global groupsWrap\n");
1394             ACTION("Non-boolean value ignored\n");
1395             ret = False;
1396         }
1397         else {
1398             if (tmp.uval)
1399                 info->groupInfo = XkbWrapIntoRange;
1400             else
1401                 info->groupInfo = XkbClampIntoRange;
1402             ret = True;
1403         }
1404     }
1405     else if ((elem.str == NULL)
1406              && ((uStrCaseCmp(field.str, "groupsclamp") == 0)
1407                  || (uStrCaseCmp(field.str, "clampgroups") == 0)))
1408     {
1409         if (!ExprResolveBoolean(stmt->value, &tmp))
1410         {
1411             ERROR("Illegal setting for global groupsClamp\n");
1412             ACTION("Non-boolean value ignored\n");
1413             return False;
1414         }
1415         else {
1416             if (tmp.uval)
1417                 info->groupInfo = XkbClampIntoRange;
1418             else
1419                 info->groupInfo = XkbWrapIntoRange;
1420             ret = True;
1421         }
1422     }
1423     else if ((elem.str == NULL)
1424              && ((uStrCaseCmp(field.str, "groupsredirect") == 0)
1425                  || (uStrCaseCmp(field.str, "redirectgroups") == 0)))
1426     {
1427         if (!ExprResolveGroup(stmt->value, &tmp))
1428         {
1429             ERROR("Illegal group index for global groupsRedirect\n");
1430             ACTION("Definition with non-integer group ignored\n");
1431             ret = False;
1432         }
1433         else {
1434             info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange,
1435                                               tmp.uval);
1436             ret = True;
1437         }
1438     }
1439     else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0))
1440     {
1441         ret = SetAllowNone(&info->dflt, arrayNdx, stmt->value);
1442     }
1443     else {
1444         ret = SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1445                              &info->action);
1446     }
1447
1448     free(elem.str);
1449     free(field.str);
1450     return ret;
1451 }
1452
1453 static Bool
1454 HandleSymbolsBody(VarDef * def,
1455                   struct xkb_desc * xkb, KeyInfo * key, SymbolsInfo * info)
1456 {
1457     Bool ok = True;
1458     ExprResult tmp, field;
1459     ExprDef *arrayNdx;
1460
1461     for (; def != NULL; def = (VarDef *) def->common.next)
1462     {
1463         if ((def->name) && (def->name->type == ExprFieldRef))
1464         {
1465             ok = HandleSymbolsVar(def, xkb, info);
1466             continue;
1467         }
1468         else
1469         {
1470             if (def->name == NULL)
1471             {
1472                 if ((def->value == NULL)
1473                     || (def->value->op == ExprKeysymList))
1474                     field.str = strdup("symbols");
1475                 else
1476                     field.str = strdup("actions");
1477                 arrayNdx = NULL;
1478             }
1479             else
1480             {
1481                 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1482             }
1483             if (ok)
1484                 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1485                                      def->value, info);
1486             free(field.str);
1487         }
1488     }
1489     return ok;
1490 }
1491
1492 static Bool
1493 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1494 {
1495     unsigned group = info->explicit_group;
1496
1497     if (group == 0)
1498         return True;
1499
1500     if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1501     {
1502         int i;
1503         WARN("For the map %s an explicit group specified\n", info->name);
1504         WARN("but key %s has more than one group defined\n",
1505               longText(key->name));
1506         ACTION("All groups except first one will be ignored\n");
1507         for (i = 1; i < XkbNumKbdGroups; i++)
1508         {
1509             key->numLevels[i] = 0;
1510             if (key->syms[i] != NULL)
1511                 free(key->syms[i]);
1512             key->syms[i] = (uint32_t *) NULL;
1513             if (key->acts[i] != NULL)
1514                 free(key->acts[i]);
1515             key->acts[i] = (union xkb_action *) NULL;
1516             key->types[i] = (uint32_t) 0;
1517         }
1518     }
1519     key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1520
1521     key->numLevels[group] = key->numLevels[0];
1522     key->numLevels[0] = 0;
1523     key->syms[group] = key->syms[0];
1524     key->syms[0] = (uint32_t *) NULL;
1525     key->acts[group] = key->acts[0];
1526     key->acts[0] = (union xkb_action *) NULL;
1527     key->types[group] = key->types[0];
1528     key->types[0] = (uint32_t) 0;
1529     return True;
1530 }
1531
1532 static int
1533 HandleSymbolsDef(SymbolsDef * stmt,
1534                  struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1535 {
1536     KeyInfo key;
1537
1538     InitKeyInfo(&key);
1539     CopyKeyInfo(&info->dflt, &key, False);
1540     key.defs.merge = stmt->merge;
1541     key.name = KeyNameToLong(stmt->keyName);
1542     if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1543     {
1544         info->errorCount++;
1545         return False;
1546     }
1547
1548     if (!SetExplicitGroup(info, &key))
1549     {
1550         info->errorCount++;
1551         return False;
1552     }
1553
1554     if (!AddKeySymbols(info, &key, xkb))
1555     {
1556         info->errorCount++;
1557         return False;
1558     }
1559     return True;
1560 }
1561
1562 static Bool
1563 HandleModMapDef(ModMapDef * def,
1564                 struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1565 {
1566     ExprDef *key;
1567     ModMapEntry tmp;
1568     ExprResult rtrn;
1569     Bool ok;
1570
1571     if (!LookupModIndex(NULL, def->modifier, TypeInt, &rtrn))
1572     {
1573         ERROR("Illegal modifier map definition\n");
1574         ACTION("Ignoring map for non-modifier \"%s\"\n",
1575                 XkbcAtomText(def->modifier));
1576         return False;
1577     }
1578     ok = True;
1579     tmp.modifier = rtrn.uval;
1580     for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1581     {
1582         if ((key->op == ExprValue) && (key->type == TypeKeyName))
1583         {
1584             tmp.haveSymbol = False;
1585             tmp.u.keyName = KeyNameToLong(key->value.keyName);
1586         }
1587         else if (ExprResolveKeySym(key, &rtrn))
1588         {
1589             tmp.haveSymbol = True;
1590             tmp.u.keySym = rtrn.uval;
1591         }
1592         else
1593         {
1594             ERROR("Modmap entries may contain only key names or keysyms\n");
1595             ACTION("Illegal definition for %s modifier ignored\n",
1596                     XkbcModIndexText(tmp.modifier));
1597             continue;
1598         }
1599
1600         ok = AddModMapEntry(info, &tmp) && ok;
1601     }
1602     return ok;
1603 }
1604
1605 static void
1606 HandleSymbolsFile(XkbFile * file,
1607                   struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1608 {
1609     ParseCommon *stmt;
1610
1611     info->name = _XkbDupString(file->name);
1612     stmt = file->defs;
1613     while (stmt)
1614     {
1615         switch (stmt->stmtType)
1616         {
1617         case StmtInclude:
1618             if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1619                                       HandleSymbolsFile))
1620                 info->errorCount++;
1621             break;
1622         case StmtSymbolsDef:
1623             if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1624                 info->errorCount++;
1625             break;
1626         case StmtVarDef:
1627             if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1628                 info->errorCount++;
1629             break;
1630         case StmtVModDef:
1631             if (!HandleVModDef((VModDef *) stmt, xkb, merge, &info->vmods))
1632                 info->errorCount++;
1633             break;
1634         case StmtInterpDef:
1635             ERROR("Interpretation files may not include other types\n");
1636             ACTION("Ignoring definition of symbol interpretation\n");
1637             info->errorCount++;
1638             break;
1639         case StmtKeycodeDef:
1640             ERROR("Interpretation files may not include other types\n");
1641             ACTION("Ignoring definition of key name\n");
1642             info->errorCount++;
1643             break;
1644         case StmtModMapDef:
1645             if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1646                 info->errorCount++;
1647             break;
1648         default:
1649             WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1650                   stmt->stmtType);
1651             break;
1652         }
1653         stmt = stmt->next;
1654         if (info->errorCount > 10)
1655         {
1656 #ifdef NOISY
1657             ERROR("Too many errors\n");
1658 #endif
1659             ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1660             break;
1661         }
1662     }
1663     return;
1664 }
1665
1666 static Bool
1667 FindKeyForSymbol(struct xkb_desc * xkb, uint32_t sym, xkb_keycode_t *kc_rtrn)
1668 {
1669     register int i, j;
1670     register Bool gotOne;
1671
1672     j = 0;
1673     do
1674     {
1675         gotOne = False;
1676         for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1677         {
1678             if (j < (int) XkbKeyNumSyms(xkb, i))
1679             {
1680                 gotOne = True;
1681                 if ((XkbKeySym(xkb, i, j) == sym))
1682                 {
1683                     *kc_rtrn = i;
1684                     return True;
1685                 }
1686             }
1687         }
1688         j++;
1689     }
1690     while (gotOne);
1691     return False;
1692 }
1693
1694 /**
1695  * Find the given name in the xkb->map->types and return its index.
1696  *
1697  * @param name The atom to search for.
1698  * @param type_rtrn Set to the index of the name if found.
1699  *
1700  * @return True if found, False otherwise.
1701  */
1702 static Bool
1703 FindNamedType(struct xkb_desc * xkb, uint32_t name, unsigned *type_rtrn)
1704 {
1705     register unsigned n;
1706
1707     if (xkb && xkb->map && xkb->map->types)
1708     {
1709         for (n = 0; n < xkb->map->num_types; n++)
1710         {
1711             if (xkb->map->types[n].name == (uint32_t) name)
1712             {
1713                 *type_rtrn = n;
1714                 return True;
1715             }
1716         }
1717     }
1718     return False;
1719 }
1720
1721 /**
1722  * Assign a type to the given sym and return the Atom for the type assigned.
1723  *
1724  * Simple recipe:
1725  * - ONE_LEVEL for width 0/1
1726  * - ALPHABETIC for 2 shift levels, with lower/upercase
1727  * - KEYPAD for keypad keys.
1728  * - TWO_LEVEL for other 2 shift level keys.
1729  * and the same for four level keys.
1730  *
1731  * @param width Number of sysms in syms.
1732  * @param syms The keysyms for the given key (must be size width).
1733  * @param typeNameRtrn Set to the Atom of the type name.
1734  *
1735  * @returns True if a type could be found, False otherwise.
1736  */
1737 static Bool
1738 FindAutomaticType(int width, uint32_t * syms, uint32_t * typeNameRtrn,
1739                   Bool * autoType)
1740 {
1741     *autoType = False;
1742     if ((width == 1) || (width == 0))
1743     {
1744         *typeNameRtrn = xkb_intern_atom("ONE_LEVEL");
1745         *autoType = True;
1746     }
1747     else if (width == 2)
1748     {
1749         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1750         {
1751             *typeNameRtrn = xkb_intern_atom("ALPHABETIC");
1752         }
1753         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1754         {
1755             *typeNameRtrn = xkb_intern_atom("KEYPAD");
1756             *autoType = True;
1757         }
1758         else
1759         {
1760             *typeNameRtrn = xkb_intern_atom("TWO_LEVEL");
1761             *autoType = True;
1762         }
1763     }
1764     else if (width <= 4)
1765     {
1766         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1767             if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1768                 *typeNameRtrn =
1769                     xkb_intern_atom("FOUR_LEVEL_ALPHABETIC");
1770             else
1771                 *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_SEMIALPHABETIC");
1772
1773         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1774             *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_KEYPAD");
1775         else
1776             *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL");
1777         /* XXX: why not set autoType here? */
1778     }
1779     return ((width >= 0) && (width <= 4));
1780 }
1781
1782 /**
1783  * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1784  * groups, and reduce to one group if all groups are identical anyway.
1785  */
1786 static void
1787 PrepareKeyDef(KeyInfo * key)
1788 {
1789     int i, j, width, defined, lastGroup;
1790     Bool identical;
1791
1792     defined = key->symsDefined | key->actsDefined | key->typesDefined;
1793     /* get highest group number */
1794     for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1795     {
1796         if (defined & (1 << i))
1797             break;
1798     }
1799     lastGroup = i;
1800
1801     if (lastGroup == 0)
1802         return;
1803
1804     /* If there are empty groups between non-empty ones fill them with data */
1805     /* from the first group. */
1806     /* We can make a wrong assumption here. But leaving gaps is worse. */
1807     for (i = lastGroup; i > 0; i--)
1808     {
1809         if (defined & (1 << i))
1810             continue;
1811         width = key->numLevels[0];
1812         if (key->typesDefined & 1)
1813         {
1814             for (j = 0; j < width; j++)
1815             {
1816                 key->types[i] = key->types[0];
1817             }
1818             key->typesDefined |= 1 << i;
1819         }
1820         if ((key->actsDefined & 1) && key->acts[0])
1821         {
1822             key->acts[i] = uTypedCalloc(width, union xkb_action);
1823             if (key->acts[i] == NULL)
1824                 continue;
1825             memcpy((void *) key->acts[i], (void *) key->acts[0],
1826                    width * sizeof(union xkb_action));
1827             key->actsDefined |= 1 << i;
1828         }
1829         if ((key->symsDefined & 1) && key->syms[0])
1830         {
1831             key->syms[i] = uTypedCalloc(width, uint32_t);
1832             if (key->syms[i] == NULL)
1833                 continue;
1834             memcpy((void *) key->syms[i], (void *) key->syms[0],
1835                    width * sizeof(uint32_t));
1836             key->symsDefined |= 1 << i;
1837         }
1838         if (defined & 1)
1839         {
1840             key->numLevels[i] = key->numLevels[0];
1841         }
1842     }
1843     /* If all groups are completely identical remove them all */
1844     /* exept the first one. */
1845     identical = True;
1846     for (i = lastGroup; i > 0; i--)
1847     {
1848         if ((key->numLevels[i] != key->numLevels[0]) ||
1849             (key->types[i] != key->types[0]))
1850         {
1851             identical = False;
1852             break;
1853         }
1854         if ((key->syms[i] != key->syms[0]) &&
1855             (key->syms[i] == NULL || key->syms[0] == NULL ||
1856              memcmp((void *) key->syms[i], (void *) key->syms[0],
1857                     sizeof(uint32_t) * key->numLevels[0])))
1858         {
1859             identical = False;
1860             break;
1861         }
1862         if ((key->acts[i] != key->acts[0]) &&
1863             (key->acts[i] == NULL || key->acts[0] == NULL ||
1864              memcmp((void *) key->acts[i], (void *) key->acts[0],
1865                     sizeof(union xkb_action) * key->numLevels[0])))
1866         {
1867             identical = False;
1868             break;
1869         }
1870     }
1871     if (identical)
1872     {
1873         for (i = lastGroup; i > 0; i--)
1874         {
1875             key->numLevels[i] = 0;
1876             if (key->syms[i] != NULL)
1877                 free(key->syms[i]);
1878             key->syms[i] = (uint32_t *) NULL;
1879             if (key->acts[i] != NULL)
1880                 free(key->acts[i]);
1881             key->acts[i] = (union xkb_action *) NULL;
1882             key->types[i] = (uint32_t) 0;
1883         }
1884         key->symsDefined &= 1;
1885         key->actsDefined &= 1;
1886         key->typesDefined &= 1;
1887     }
1888     return;
1889 }
1890
1891 /**
1892  * Copy the KeyInfo into the keyboard description.
1893  *
1894  * This function recurses.
1895  */
1896 static Bool
1897 CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from)
1898 {
1899     register int i;
1900     xkb_keycode_t okc, kc;
1901     unsigned width, tmp, nGroups;
1902     struct xkb_key_type * type;
1903     Bool haveActions, autoType, useAlias;
1904     uint32_t *outSyms;
1905     union xkb_action *outActs;
1906     unsigned types[XkbNumKbdGroups];
1907
1908     useAlias = (start_from == 0);
1909
1910     /* get the keycode for the key. */
1911     if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1912                       start_from))
1913     {
1914         if ((start_from == 0) && (warningLevel >= 5))
1915         {
1916             WARN("Key %s not found in %s keycodes\n",
1917                   longText(key->name),
1918                   XkbcAtomText(xkb->names->keycodes));
1919             ACTION("Symbols ignored\n");
1920         }
1921         return False;
1922     }
1923
1924     haveActions = False;
1925     for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1926     {
1927         if (((i + 1) > nGroups)
1928             && (((key->symsDefined | key->actsDefined) & (1 << i))
1929                 || (key->typesDefined) & (1 << i)))
1930             nGroups = i + 1;
1931         if (key->acts[i])
1932             haveActions = True;
1933         autoType = False;
1934         /* Assign the type to the key, if it is missing. */
1935         if (key->types[i] == None)
1936         {
1937             if (key->dfltType != None)
1938                 key->types[i] = key->dfltType;
1939             else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1940                                        &key->types[i], &autoType))
1941             {
1942             }
1943             else
1944             {
1945                 if (warningLevel >= 5)
1946                 {
1947                     WARN("No automatic type for %d symbols\n",
1948                           (unsigned int) key->numLevels[i]);
1949                     ACTION("Using %s for the %s key (keycode %d)\n",
1950                             XkbcAtomText(key->types[i]),
1951                             longText(key->name), kc);
1952                 }
1953             }
1954         }
1955         if (FindNamedType(xkb, key->types[i], &types[i]))
1956         {
1957             if (!autoType || key->numLevels[i] > 2)
1958                 xkb->server->explicit[kc] |= (1 << i);
1959         }
1960         else
1961         {
1962             if (warningLevel >= 3)
1963             {
1964                 WARN("Type \"%s\" is not defined\n",
1965                       XkbcAtomText(key->types[i]));
1966                 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
1967                         longText(key->name), kc);
1968             }
1969             types[i] = XkbTwoLevelIndex;
1970         }
1971         /* if the type specifies less syms than the key has, shrink the key */
1972         type = &xkb->map->types[types[i]];
1973         if (type->num_levels < key->numLevels[i])
1974         {
1975             if (warningLevel > 0)
1976             {
1977                 WARN
1978                     ("Type \"%s\" has %d levels, but %s has %d symbols\n",
1979                      XkbcAtomText(type->name),
1980                      (unsigned int) type->num_levels,
1981                      longText(key->name),
1982                      (unsigned int) key->numLevels[i]);
1983                 ACTION("Ignoring extra symbols\n");
1984             }
1985             key->numLevels[i] = type->num_levels;
1986         }
1987         if (key->numLevels[i] > width)
1988             width = key->numLevels[i];
1989         if (type->num_levels > width)
1990             width = type->num_levels;
1991     }
1992
1993     /* width is now the largest width found */
1994
1995     i = width * nGroups;
1996     outSyms = XkbcResizeKeySyms(xkb, kc, i);
1997     if (outSyms == NULL)
1998     {
1999         WSGO("Could not enlarge symbols for %s (keycode %d)\n",
2000               longText(key->name), kc);
2001         return False;
2002     }
2003     if (haveActions)
2004     {
2005         outActs = XkbcResizeKeyActions(xkb, kc, i);
2006         if (outActs == NULL)
2007         {
2008             WSGO("Could not enlarge actions for %s (key %d)\n",
2009                   longText(key->name), kc);
2010             return False;
2011         }
2012         xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
2013     }
2014     else
2015         outActs = NULL;
2016     if (key->defs.defined & _Key_GroupInfo)
2017         i = key->groupInfo;
2018     else
2019         i = xkb->map->key_sym_map[kc].group_info;
2020
2021     xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2022     xkb->map->key_sym_map[kc].width = width;
2023     for (i = 0; i < nGroups; i++)
2024     {
2025         /* assign kt_index[i] to the index of the type in map->types.
2026          * kt_index[i] may have been set by a previous run (if we have two
2027          * layouts specified). Let's not overwrite it with the ONE_LEVEL
2028          * default group if we dont even have keys for this group anyway.
2029          *
2030          * FIXME: There should be a better fix for this.
2031          */
2032         if (key->numLevels[i])
2033             xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2034         if (key->syms[i] != NULL)
2035         {
2036             /* fill key to "width" symbols*/
2037             for (tmp = 0; tmp < width; tmp++)
2038             {
2039                 if (tmp < key->numLevels[i])
2040                     outSyms[tmp] = key->syms[i][tmp];
2041                 else
2042                     outSyms[tmp] = NoSymbol;
2043                 if ((outActs != NULL) && (key->acts[i] != NULL))
2044                 {
2045                     if (tmp < key->numLevels[i])
2046                         outActs[tmp] = key->acts[i][tmp];
2047                     else
2048                         outActs[tmp].type = XkbSA_NoAction;
2049                 }
2050             }
2051         }
2052         outSyms += width;
2053         if (outActs)
2054             outActs += width;
2055     }
2056     switch (key->behavior.type & XkbKB_OpMask)
2057     {
2058     case XkbKB_Default:
2059         break;
2060     case XkbKB_Overlay1:
2061     case XkbKB_Overlay2:
2062         /* find key by name! */
2063         if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True,
2064                           CreateKeyNames(xkb), 0))
2065         {
2066             if (warningLevel >= 1)
2067             {
2068                 WARN("Key %s not found in %s keycodes\n",
2069                       longText(key->nameForOverlayKey),
2070                       XkbcAtomText(xkb->names->keycodes));
2071                 ACTION("Not treating %s as an overlay key \n",
2072                         longText(key->name));
2073             }
2074             break;
2075         }
2076         key->behavior.data = okc;
2077     default:
2078         xkb->server->behaviors[kc] = key->behavior;
2079         xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2080         break;
2081     }
2082     if (key->defs.defined & _Key_VModMap)
2083     {
2084         xkb->server->vmodmap[kc] = key->vmodmap;
2085         xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2086     }
2087     if (key->repeat != RepeatUndefined)
2088     {
2089         if (key->repeat == RepeatYes)
2090             xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2091         else
2092             xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2093         xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2094     }
2095
2096     if (nGroups > xkb->ctrls->num_groups)
2097         xkb->ctrls->num_groups = nGroups;
2098
2099     /* do the same thing for the next key */
2100     CopySymbolsDef(xkb, key, kc + 1);
2101     return True;
2102 }
2103
2104 static Bool
2105 CopyModMapDef(struct xkb_desc * xkb, ModMapEntry *entry)
2106 {
2107     xkb_keycode_t kc;
2108
2109     if ((!entry->haveSymbol)
2110         &&
2111         (!FindNamedKey
2112          (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
2113     {
2114         if (warningLevel >= 5)
2115         {
2116             WARN("Key %s not found in %s keycodes\n",
2117                   longText(entry->u.keyName),
2118                   XkbcAtomText(xkb->names->keycodes));
2119             ACTION("Modifier map entry for %s not updated\n",
2120                     XkbcModIndexText(entry->modifier));
2121         }
2122         return False;
2123     }
2124     else if (entry->haveSymbol
2125              && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2126     {
2127         if (warningLevel > 5)
2128         {
2129             WARN("Key \"%s\" not found in %s symbol map\n",
2130                   XkbcKeysymText(entry->u.keySym),
2131                   XkbcAtomText(xkb->names->symbols));
2132             ACTION("Modifier map entry for %s not updated\n",
2133                     XkbcModIndexText(entry->modifier));
2134         }
2135         return False;
2136     }
2137     xkb->map->modmap[kc] |= (1 << entry->modifier);
2138     return True;
2139 }
2140
2141 /**
2142  * Handle the xkb_symbols section of an xkb file.
2143  *
2144  * @param file The parsed xkb_symbols section of the xkb file.
2145  * @param xkb Handle to the keyboard description to store the symbols in.
2146  * @param merge Merge strategy (e.g. MergeOverride).
2147  */
2148 Bool
2149 CompileSymbols(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
2150 {
2151     register int i;
2152     SymbolsInfo info;
2153
2154     InitSymbolsInfo(&info, xkb);
2155     info.dflt.defs.fileID = file->id;
2156     info.dflt.defs.merge = merge;
2157     HandleSymbolsFile(file, xkb, merge, &info);
2158
2159     if (info.nKeys == 0) {
2160         FreeSymbolsInfo(&info);
2161         return True;
2162     }
2163
2164     if (info.errorCount == 0)
2165     {
2166         KeyInfo *key;
2167
2168         /* alloc memory in the xkb struct */
2169         if (XkbcAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0)
2170             != Success)
2171         {
2172             WSGO("Can not allocate names in CompileSymbols\n");
2173             ACTION("Symbols not added\n");
2174             return False;
2175         }
2176         if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2177             != Success)
2178         {
2179             WSGO("Could not allocate client map in CompileSymbols\n");
2180             ACTION("Symbols not added\n");
2181             return False;
2182         }
2183         if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2184         {
2185             WSGO("Could not allocate server map in CompileSymbols\n");
2186             ACTION("Symbols not added\n");
2187             return False;
2188         }
2189         if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2190         {
2191             WSGO("Could not allocate controls in CompileSymbols\n");
2192             ACTION("Symbols not added\n");
2193             return False;
2194         }
2195
2196         /* now copy info into xkb. */
2197         xkb->names->symbols = xkb_intern_atom(info.name);
2198         if (info.aliases)
2199             ApplyAliases(xkb, False, &info.aliases);
2200         for (i = 0; i < XkbNumKbdGroups; i++)
2201         {
2202             if (info.groupNames[i] != None)
2203                 xkb->names->groups[i] = info.groupNames[i];
2204         }
2205         /* sanitize keys */
2206         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2207         {
2208             PrepareKeyDef(key);
2209         }
2210         /* copy! */
2211         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2212         {
2213             if (!CopySymbolsDef(xkb, key, 0))
2214                 info.errorCount++;
2215         }
2216         if (warningLevel > 3)
2217         {
2218             for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2219             {
2220                 if (xkb->names->keys[i].name[0] == '\0')
2221                     continue;
2222                 if (XkbKeyNumGroups(xkb, i) < 1)
2223                 {
2224                     char buf[5];
2225                     memcpy(buf, xkb->names->keys[i].name, 4);
2226                     buf[4] = '\0';
2227                     WARN
2228                         ("No symbols defined for <%s> (keycode %d)\n",
2229                          buf, i);
2230                 }
2231             }
2232         }
2233         if (info.modMap)
2234         {
2235             ModMapEntry *mm, *next;
2236             for (mm = info.modMap; mm != NULL; mm = next)
2237             {
2238                 if (!CopyModMapDef(xkb, mm))
2239                     info.errorCount++;
2240                 next = (ModMapEntry *) mm->defs.next;
2241             }
2242         }
2243         FreeSymbolsInfo(&info);
2244         return True;
2245     }
2246
2247     FreeSymbolsInfo(&info);
2248     return False;
2249 }