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