Still more memory leak fixes
[platform/upstream/libxkbcommon.git] / src / xkbcomp / keycodes.c
1 /************************************************************
2  Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3
4  Permission to use, copy, modify, and distribute this
5  software and its documentation for any purpose and without
6  fee is hereby granted, provided that the above copyright
7  notice appear in all copies and that both that copyright
8  notice and this permission notice appear in supporting
9  documentation, and that the name of Silicon Graphics not be
10  used in advertising or publicity pertaining to distribution
11  of the software without specific prior written permission.
12  Silicon Graphics makes no representation about the suitability
13  of this software for any purpose. It is provided "as is"
14  without any express or implied warranty.
15
16  SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19  GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23  THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25  ********************************************************/
26
27 #include "xkbcomp.h"
28 #include "xkballoc.h"
29 #include "xkbmisc.h"
30 #include "tokens.h"
31 #include "expr.h"
32 #include "keycodes.h"
33 #include "misc.h"
34 #include "alias.h"
35
36 char *
37 longText(unsigned long val)
38 {
39     char buf[4];
40
41     LongToKeyName(val, buf);
42     return XkbcKeyNameText(buf);
43 }
44
45 /***====================================================================***/
46
47 void
48 LongToKeyName(unsigned long val, char *name)
49 {
50     name[0] = ((val >> 24) & 0xff);
51     name[1] = ((val >> 16) & 0xff);
52     name[2] = ((val >> 8) & 0xff);
53     name[3] = (val & 0xff);
54     return;
55 }
56
57 /***====================================================================***/
58
59 typedef struct _IndicatorNameInfo
60 {
61     CommonInfo defs;
62     int ndx;
63     uint32_t name;
64     Bool virtual;
65 } IndicatorNameInfo;
66
67 typedef struct _KeyNamesInfo
68 {
69     char *name;     /* e.g. evdev+aliases(qwerty) */
70     int errorCount;
71     unsigned fileID;
72     unsigned merge;
73     xkb_keycode_t computedMin; /* lowest keycode stored */
74     xkb_keycode_t computedMax; /* highest keycode stored */
75     xkb_keycode_t explicitMin;
76     xkb_keycode_t explicitMax;
77     xkb_keycode_t arraySize;
78     unsigned long *names;
79     unsigned *files;
80     unsigned char *has_alt_forms;
81     IndicatorNameInfo *leds;
82     AliasInfo *aliases;
83 } KeyNamesInfo;
84
85 static void HandleKeycodesFile(XkbFile * file,
86                                struct xkb_desc * xkb,
87                                unsigned merge,
88                                KeyNamesInfo * info);
89
90 static int
91 ResizeKeyNameArrays(KeyNamesInfo *info, int newMax)
92 {
93     void *tmp;
94     int i;
95
96     tmp = _XkbTypedRealloc(info->names, newMax + 1, unsigned long);
97     if (!tmp) {
98         ERROR
99             ("Couldn't reallocate for larger maximum keycode (%d)\n",
100              newMax);
101         ACTION("Maximum key value not changed\n");
102         return 0;
103     }
104     info->names = tmp;
105     for (i = info->arraySize + 1; i <= newMax; i++)
106         info->names[i] = 0;
107
108     tmp = _XkbTypedRealloc(info->files, newMax + 1, unsigned);
109     if (!tmp) {
110         ERROR
111             ("Couldn't reallocate for larger maximum keycode (%d)\n",
112              newMax);
113         ACTION("Maximum key value not changed\n");
114         return 0;
115     }
116     info->files = tmp;
117     for (i = info->arraySize + 1; i <= newMax; i++)
118         info->files[i] = 0;
119
120     tmp = _XkbTypedRealloc(info->has_alt_forms, newMax + 1, unsigned char);
121     if (!tmp) {
122         ERROR
123             ("Couldn't reallocate for larger maximum keycode (%d)\n",
124              newMax);
125         ACTION("Maximum key value not changed\n");
126         return 0;
127     }
128     info->has_alt_forms = tmp;
129     for (i = info->arraySize + 1; i <= newMax; i++)
130         info->has_alt_forms[i] = 0;
131
132     info->arraySize = newMax;
133
134     return 1;
135 }
136
137 static void
138 InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
139 {
140     ii->defs.defined = 0;
141     ii->defs.merge = info->merge;
142     ii->defs.fileID = info->fileID;
143     ii->defs.next = NULL;
144     ii->ndx = 0;
145     ii->name = None;
146     ii->virtual = False;
147     return;
148 }
149
150 static void
151 ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
152 {
153     if (ii == info->leds)
154     {
155         ClearCommonInfo(&ii->defs);
156         info->leds = NULL;
157     }
158     return;
159 }
160
161 static IndicatorNameInfo *
162 NextIndicatorName(KeyNamesInfo * info)
163 {
164     IndicatorNameInfo *ii;
165
166     ii = uTypedAlloc(IndicatorNameInfo);
167     if (ii)
168     {
169         InitIndicatorNameInfo(ii, info);
170         info->leds = (IndicatorNameInfo *) AddCommonInfo(&info->leds->defs,
171                                                          (CommonInfo *) ii);
172     }
173     return ii;
174 }
175
176 static IndicatorNameInfo *
177 FindIndicatorByIndex(KeyNamesInfo * info, int ndx)
178 {
179     IndicatorNameInfo *old;
180
181     for (old = info->leds; old != NULL;
182          old = (IndicatorNameInfo *) old->defs.next)
183     {
184         if (old->ndx == ndx)
185             return old;
186     }
187     return NULL;
188 }
189
190 static IndicatorNameInfo *
191 FindIndicatorByName(KeyNamesInfo * info, uint32_t name)
192 {
193     IndicatorNameInfo *old;
194
195     for (old = info->leds; old != NULL;
196          old = (IndicatorNameInfo *) old->defs.next)
197     {
198         if (old->name == name)
199             return old;
200     }
201     return NULL;
202 }
203
204 static Bool
205 AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
206 {
207     IndicatorNameInfo *old;
208     Bool replace;
209
210     replace = (new->defs.merge == MergeReplace) ||
211         (new->defs.merge == MergeOverride);
212     old = FindIndicatorByName(info, new->name);
213     if (old)
214     {
215         if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
216             || (warningLevel > 9))
217         {
218             WARN("Multiple indicators named %s\n", XkbcAtomText(new->name));
219             if (old->ndx == new->ndx)
220             {
221                 if (old->virtual != new->virtual)
222                 {
223                     if (replace)
224                         old->virtual = new->virtual;
225                     ACTION("Using %s instead of %s\n",
226                            (old->virtual ? "virtual" : "real"),
227                            (old->virtual ? "real" : "virtual"));
228                 }
229                 else
230                 {
231                     ACTION("Identical definitions ignored\n");
232                 }
233                 return True;
234             }
235             else
236             {
237                 if (replace)
238                     ACTION("Ignoring %d, using %d\n", old->ndx, new->ndx);
239                 else
240                     ACTION("Using %d, ignoring %d\n", old->ndx, new->ndx);
241             }
242             if (replace)
243             {
244                 if (info->leds == old)
245                     info->leds = (IndicatorNameInfo *) old->defs.next;
246                 else
247                 {
248                     IndicatorNameInfo *tmp;
249                     tmp = info->leds;
250                     for (; tmp != NULL;
251                          tmp = (IndicatorNameInfo *) tmp->defs.next)
252                     {
253                         if (tmp->defs.next == (CommonInfo *) old)
254                         {
255                             tmp->defs.next = old->defs.next;
256                             break;
257                         }
258                     }
259                 }
260                 free(old);
261             }
262         }
263     }
264     old = FindIndicatorByIndex(info, new->ndx);
265     if (old)
266     {
267         if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
268             || (warningLevel > 9))
269         {
270             WARN("Multiple names for indicator %d\n", new->ndx);
271             if ((old->name == new->name) && (old->virtual == new->virtual))
272                 ACTION("Identical definitions ignored\n");
273             else
274             {
275                 const char *oldType, *newType;
276                 uint32_t using, ignoring;
277                 if (old->virtual)
278                     oldType = "virtual indicator";
279                 else
280                     oldType = "real indicator";
281                 if (new->virtual)
282                     newType = "virtual indicator";
283                 else
284                     newType = "real indicator";
285                 if (replace)
286                 {
287                     using = new->name;
288                     ignoring = old->name;
289                 }
290                 else
291                 {
292                     using = old->name;
293                     ignoring = new->name;
294                 }
295                 ACTION("Using %s %s, ignoring %s %s\n",
296                         oldType, XkbcAtomText(using),
297                         newType, XkbcAtomText(ignoring));
298             }
299         }
300         if (replace)
301         {
302             old->name = new->name;
303             old->virtual = new->virtual;
304         }
305         return True;
306     }
307     old = new;
308     new = NextIndicatorName(info);
309     if (!new)
310     {
311         WSGO("Couldn't allocate name for indicator %d\n", new->ndx);
312         ACTION("Ignored\n");
313         return False;
314     }
315     new->name = old->name;
316     new->ndx = old->ndx;
317     new->virtual = old->virtual;
318     return True;
319 }
320
321 static void
322 ClearKeyNamesInfo(KeyNamesInfo * info)
323 {
324     if (info->name != NULL)
325         free(info->name);
326     info->name = NULL;
327     info->computedMax = info->explicitMax = info->explicitMin = 0;
328     info->computedMin = XKB_KEYCODE_MAX;
329     info->arraySize = 0;
330     free(info->names);
331     info->names = NULL;
332     free(info->files);
333     info->files = NULL;
334     free(info->has_alt_forms);
335     info->has_alt_forms = NULL;
336     if (info->leds)
337         ClearIndicatorNameInfo(info->leds, info);
338     if (info->aliases)
339         ClearAliases(&info->aliases);
340     return;
341 }
342
343 static void
344 InitKeyNamesInfo(KeyNamesInfo * info)
345 {
346     info->name = NULL;
347     info->leds = NULL;
348     info->aliases = NULL;
349     info->names = NULL;
350     info->files = NULL;
351     info->has_alt_forms = NULL;
352     ClearKeyNamesInfo(info);
353     info->errorCount = 0;
354     return;
355 }
356
357 static int
358 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
359 {
360     register int i;
361
362     for (i = info->computedMin; i <= info->computedMax; i++)
363     {
364         if (info->names[i] == name)
365             return i;
366     }
367     return 0;
368 }
369
370 /**
371  * Store the name of the key as a long in the info struct under the given
372  * keycode. If the same keys is referred to twice, print a warning.
373  * Note that the key's name is stored as a long, the keycode is the index.
374  */
375 static Bool
376 AddKeyName(KeyNamesInfo * info,
377            xkb_keycode_t kc,
378            char *name, unsigned merge, unsigned fileID, Bool reportCollisions)
379 {
380     int old;
381     unsigned long lval;
382
383     if (kc > info->arraySize && !ResizeKeyNameArrays(info, kc)) {
384         ERROR("Couldn't resize KeyNames arrays for keycode %d\n", kc);
385         ACTION("Ignoring key %d\n", kc);
386         return False;
387     }
388     if (kc < info->computedMin)
389         info->computedMin = kc;
390     if (kc > info->computedMax)
391         info->computedMax = kc;
392     lval = KeyNameToLong(name);
393
394     if (reportCollisions)
395     {
396         reportCollisions = ((warningLevel > 7) ||
397                             ((warningLevel > 0)
398                              && (fileID == info->files[kc])));
399     }
400
401     if (info->names[kc] != 0)
402     {
403         char buf[6];
404
405         LongToKeyName(info->names[kc], buf);
406         buf[4] = '\0';
407         if (info->names[kc] == lval)
408         {
409             if (info->has_alt_forms[kc] || (merge == MergeAltForm))
410             {
411                 info->has_alt_forms[kc] = True;
412             }
413             else if (reportCollisions)
414             {
415                 WARN("Multiple identical key name definitions\n");
416                 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
417                         buf, kc);
418             }
419             return True;
420         }
421         if (merge == MergeAugment)
422         {
423             if (reportCollisions)
424             {
425                 WARN("Multiple names for keycode %d\n", kc);
426                 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
427             }
428             return True;
429         }
430         else
431         {
432             if (reportCollisions)
433             {
434                 WARN("Multiple names for keycode %d\n", kc);
435                 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
436             }
437             info->names[kc] = 0;
438             info->files[kc] = 0;
439         }
440     }
441     old = FindKeyByLong(info, lval);
442     if ((old != 0) && (old != kc))
443     {
444         if (merge == MergeOverride)
445         {
446             info->names[old] = 0;
447             info->files[old] = 0;
448             info->has_alt_forms[old] = True;
449             if (reportCollisions)
450             {
451                 WARN("Key name <%s> assigned to multiple keys\n", name);
452                 ACTION("Using %d, ignoring %d\n", kc, old);
453             }
454         }
455         else if (merge != MergeAltForm)
456         {
457             if ((reportCollisions) && (warningLevel > 3))
458             {
459                 WARN("Key name <%s> assigned to multiple keys\n", name);
460                 ACTION("Using %d, ignoring %d\n", old, kc);
461                 ACTION
462                     ("Use 'alternate' keyword to assign the same name to multiple keys\n");
463             }
464             return True;
465         }
466         else
467         {
468             info->has_alt_forms[old] = True;
469         }
470     }
471     info->names[kc] = lval;
472     info->files[kc] = fileID;
473     info->has_alt_forms[kc] = (merge == MergeAltForm);
474     return True;
475 }
476
477 /***====================================================================***/
478
479 static void
480 MergeIncludedKeycodes(KeyNamesInfo * into, KeyNamesInfo * from,
481                       unsigned merge)
482 {
483     register int i;
484     char buf[5];
485
486     if (from->errorCount > 0)
487     {
488         into->errorCount += from->errorCount;
489         return;
490     }
491     if (into->name == NULL)
492     {
493         into->name = from->name;
494         from->name = NULL;
495     }
496     if (from->computedMax > into->arraySize &&
497         !ResizeKeyNameArrays(into, from->computedMax)) {
498         ERROR("Couldn't resize KeyNames arrays for key %d\n",
499               from->computedMax);
500         ACTION("Ignoring include file %s\n", from->name);
501         into->errorCount += 10;
502         return;
503     }
504     for (i = from->computedMin; i <= from->computedMax; i++)
505     {
506         unsigned thisMerge;
507         if (from->names[i] == 0)
508             continue;
509         LongToKeyName(from->names[i], buf);
510         buf[4] = '\0';
511         if (from->has_alt_forms[i])
512             thisMerge = MergeAltForm;
513         else
514             thisMerge = merge;
515         if (!AddKeyName(into, i, buf, thisMerge, from->fileID, False))
516             into->errorCount++;
517     }
518     if (from->leds)
519     {
520         IndicatorNameInfo *led, *next;
521         for (led = from->leds; led != NULL; led = next)
522         {
523             if (merge != MergeDefault)
524                 led->defs.merge = merge;
525             if (!AddIndicatorName(into, led))
526                 into->errorCount++;
527             next = (IndicatorNameInfo *) led->defs.next;
528         }
529     }
530     if (!MergeAliases(&into->aliases, &from->aliases, merge))
531         into->errorCount++;
532     if (from->explicitMin != 0)
533     {
534         if ((into->explicitMin < 0)
535             || (into->explicitMin > from->explicitMin))
536             into->explicitMin = from->explicitMin;
537     }
538     if (from->explicitMax > 0)
539     {
540         if ((into->explicitMax < 0)
541             || (into->explicitMax < from->explicitMax))
542             into->explicitMax = from->explicitMax;
543     }
544     return;
545 }
546
547 /**
548  * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
549  *
550  * @param stmt The include statement from the keymap file.
551  * @param xkb Unused for all but the xkb->flags.
552  * @param info Struct to store the key info in.
553  */
554 static Bool
555 HandleIncludeKeycodes(IncludeStmt * stmt, struct xkb_desc * xkb, KeyNamesInfo * info)
556 {
557     unsigned newMerge;
558     XkbFile *rtrn;
559     KeyNamesInfo included = {NULL};
560     Bool haveSelf;
561
562     haveSelf = False;
563     if ((stmt->file == NULL) && (stmt->map == NULL))
564     {
565         haveSelf = True;
566         included = *info;
567         bzero(info, sizeof(KeyNamesInfo));
568     }
569     else if (strcmp(stmt->file, "computed") == 0)
570     {
571         xkb->flags |= AutoKeyNames;
572         info->explicitMin = 0;
573         info->explicitMax = XKB_KEYCODE_MAX;
574         return (info->errorCount == 0);
575     } /* parse file, store returned info in the xkb struct */
576     else if (ProcessIncludeFile(stmt, XkmKeyNamesIndex, &rtrn, &newMerge))
577     {
578         InitKeyNamesInfo(&included);
579         HandleKeycodesFile(rtrn, xkb, MergeOverride, &included);
580         if (stmt->stmt != NULL)
581         {
582             if (included.name != NULL)
583                 free(included.name);
584             included.name = stmt->stmt;
585             stmt->stmt = NULL;
586         }
587     }
588     else
589     {
590         info->errorCount += 10; /* XXX: why 10?? */
591         return False;
592     }
593     /* Do we have more than one include statement? */
594     if ((stmt->next != NULL) && (included.errorCount < 1))
595     {
596         IncludeStmt *next;
597         unsigned op;
598         KeyNamesInfo next_incl;
599
600         for (next = stmt->next; next != NULL; next = next->next)
601         {
602             if ((next->file == NULL) && (next->map == NULL))
603             {
604                 haveSelf = True;
605                 MergeIncludedKeycodes(&included, info, next->merge);
606                 ClearKeyNamesInfo(info);
607             }
608             else if (ProcessIncludeFile(next, XkmKeyNamesIndex, &rtrn, &op))
609             {
610                 InitKeyNamesInfo(&next_incl);
611                 HandleKeycodesFile(rtrn, xkb, MergeOverride, &next_incl);
612                 MergeIncludedKeycodes(&included, &next_incl, op);
613                 ClearKeyNamesInfo(&next_incl);
614             }
615             else
616             {
617                 info->errorCount += 10; /* XXX: Why 10?? */
618                 ClearKeyNamesInfo(&included);
619                 return False;
620             }
621         }
622     }
623     if (haveSelf)
624         *info = included;
625     else
626     {
627         MergeIncludedKeycodes(info, &included, newMerge);
628         ClearKeyNamesInfo(&included);
629     }
630     return (info->errorCount == 0);
631 }
632
633 /**
634  * Parse the given statement and store the output in the info struct.
635  * e.g. <ESC> = 9
636  */
637 static int
638 HandleKeycodeDef(KeycodeDef * stmt, unsigned merge, KeyNamesInfo * info)
639 {
640     if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
641         (info->explicitMax != 0 && stmt->value > info->explicitMax))
642     {
643         ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
644         ACTION("Must be in the range %d-%d inclusive\n",
645                 info->explicitMin,
646                 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
647         return 0;
648     }
649     if (stmt->merge != MergeDefault)
650     {
651         if (stmt->merge == MergeReplace)
652             merge = MergeOverride;
653         else
654             merge = stmt->merge;
655     }
656     return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
657                       True);
658 }
659
660 #define MIN_KEYCODE_DEF         0
661 #define MAX_KEYCODE_DEF         1
662
663 /**
664  * Handle the minimum/maximum statement of the xkb file.
665  * Sets explicitMin/Max of the info struct.
666  *
667  * @return 1 on success, 0 otherwise.
668  */
669 static int
670 HandleKeyNameVar(VarDef * stmt, KeyNamesInfo * info)
671 {
672     ExprResult tmp, field;
673     ExprDef *arrayNdx;
674     int which;
675
676     if (ExprResolveLhs(stmt->name, &tmp, &field, &arrayNdx) == 0)
677         return 0;               /* internal error, already reported */
678
679     if (tmp.str != NULL)
680     {
681         ERROR("Unknown element %s encountered\n", tmp.str);
682         ACTION("Default for field %s ignored\n", field.str);
683         return 0;
684     }
685     if (uStrCaseCmp(field.str, "minimum") == 0)
686         which = MIN_KEYCODE_DEF;
687     else if (uStrCaseCmp(field.str, "maximum") == 0)
688         which = MAX_KEYCODE_DEF;
689     else
690     {
691         ERROR("Unknown field encountered\n");
692         ACTION("Assigment to field %s ignored\n", field.str);
693         return 0;
694     }
695     if (arrayNdx != NULL)
696     {
697         ERROR("The %s setting is not an array\n", field.str);
698         ACTION("Illegal array reference ignored\n");
699         return 0;
700     }
701
702     if (ExprResolveKeyCode(stmt->value, &tmp) == 0)
703     {
704         ACTION("Assignment to field %s ignored\n", field.str);
705         return 0;
706     }
707     if (tmp.uval > XKB_KEYCODE_MAX)
708     {
709         ERROR
710             ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
711              tmp.uval, 0, XKB_KEYCODE_MAX);
712         ACTION("Value of \"%s\" not changed\n", field.str);
713         return 0;
714     }
715     if (which == MIN_KEYCODE_DEF)
716     {
717         if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
718         {
719             ERROR
720                 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
721                  tmp.uval, info->explicitMax);
722             ACTION("Minimum key code value not changed\n");
723             return 0;
724         }
725         if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
726         {
727             ERROR
728                 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
729                  tmp.uval, info->computedMin);
730             ACTION("Minimum key code value not changed\n");
731             return 0;
732         }
733         info->explicitMin = tmp.uval;
734     }
735     if (which == MAX_KEYCODE_DEF)
736     {
737         if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
738         {
739             ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
740                    tmp.uval, info->explicitMin);
741             ACTION("Maximum code value not changed\n");
742             return 0;
743         }
744         if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
745         {
746             ERROR
747                 ("Maximum code (%d) must be >= highest defined key (%d)\n",
748                  tmp.uval, info->computedMax);
749             ACTION("Maximum code value not changed\n");
750             return 0;
751         }
752         info->explicitMax = tmp.uval;
753     }
754     return 1;
755 }
756
757 static int
758 HandleIndicatorNameDef(IndicatorNameDef * def,
759                        unsigned merge, KeyNamesInfo * info)
760 {
761     IndicatorNameInfo ii;
762     ExprResult tmp;
763
764     if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
765     {
766         info->errorCount++;
767         ERROR("Name specified for illegal indicator index %d\n", def->ndx);
768         ACTION("Ignored\n");
769         return False;
770     }
771     InitIndicatorNameInfo(&ii, info);
772     ii.ndx = def->ndx;
773     if (!ExprResolveString(def->name, &tmp, NULL, NULL))
774     {
775         char buf[20];
776         snprintf(buf, sizeof(buf), "%d", def->ndx);
777         info->errorCount++;
778         return ReportBadType("indicator", "name", buf, "string");
779     }
780     ii.name = xkb_intern_atom(tmp.str);
781     free(tmp.str);
782     ii.virtual = def->virtual;
783     if (!AddIndicatorName(info, &ii))
784         return False;
785     return True;
786 }
787
788 /**
789  * Handle the xkb_keycodes section of a xkb file.
790  * All information about parsed keys is stored in the info struct.
791  *
792  * Such a section may have include statements, in which case this function is
793  * semi-recursive (it calls HandleIncludeKeycodes, which may call
794  * HandleKeycodesFile again).
795  *
796  * @param file The input file (parsed xkb_keycodes section)
797  * @param xkb Necessary to pass down, may have flags changed.
798  * @param merge Merge strategy (MergeOverride, etc.)
799  * @param info Struct to contain the fully parsed key information.
800  */
801 static void
802 HandleKeycodesFile(XkbFile * file,
803                    struct xkb_desc * xkb, unsigned merge, KeyNamesInfo * info)
804 {
805     ParseCommon *stmt;
806
807     info->name = _XkbDupString(file->name);
808     stmt = file->defs;
809     while (stmt)
810     {
811         switch (stmt->stmtType)
812         {
813         case StmtInclude:    /* e.g. include "evdev+aliases(qwerty)" */
814             if (!HandleIncludeKeycodes((IncludeStmt *) stmt, xkb, info))
815                 info->errorCount++;
816             break;
817         case StmtKeycodeDef: /* e.g. <ESC> = 9; */
818             if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info))
819                 info->errorCount++;
820             break;
821         case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
822             if (!HandleAliasDef((KeyAliasDef *) stmt,
823                                 merge, info->fileID, &info->aliases))
824                 info->errorCount++;
825             break;
826         case StmtVarDef: /* e.g. minimum, maximum */
827             if (!HandleKeyNameVar((VarDef *) stmt, info))
828                 info->errorCount++;
829             break;
830         case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
831             if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt,
832                                         merge, info))
833             {
834                 info->errorCount++;
835             }
836             break;
837         case StmtInterpDef:
838         case StmtVModDef:
839             ERROR("Keycode files may define key and indicator names only\n");
840             ACTION("Ignoring definition of %s\n",
841                     ((stmt->stmtType ==
842                       StmtInterpDef) ? "a symbol interpretation" :
843                      "virtual modifiers"));
844             info->errorCount++;
845             break;
846         default:
847             WSGO("Unexpected statement type %d in HandleKeycodesFile\n",
848                   stmt->stmtType);
849             break;
850         }
851         stmt = stmt->next;
852         if (info->errorCount > 10)
853         {
854 #ifdef NOISY
855             ERROR("Too many errors\n");
856 #endif
857             ACTION("Abandoning keycodes file \"%s\"\n", file->topName);
858             break;
859         }
860     }
861     return;
862 }
863
864 /**
865  * Compile the xkb_keycodes section, parse it's output, return the results.
866  *
867  * @param file The parsed XKB file (may have include statements requiring
868  * further parsing)
869  * @param result The effective keycodes, as gathered from the file.
870  * @param merge Merge strategy.
871  *
872  * @return True on success, False otherwise.
873  */
874 Bool
875 CompileKeycodes(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
876 {
877     KeyNamesInfo info; /* contains all the info after parsing */
878
879     InitKeyNamesInfo(&info);
880     HandleKeycodesFile(file, xkb, merge, &info);
881
882     /* all the keys are now stored in info */
883
884     if (info.errorCount == 0)
885     {
886         if (info.explicitMin > 0) /* if "minimum" statement was present */
887             xkb->min_key_code = info.explicitMin;
888         else
889             xkb->min_key_code = info.computedMin;
890         if (info.explicitMax > 0) /* if "maximum" statement was present */
891             xkb->max_key_code = info.explicitMax;
892         else
893             xkb->max_key_code = info.computedMax;
894         if (XkbcAllocNames(xkb, XkbKeyNamesMask | XkbIndicatorNamesMask, 0, 0)
895                 == Success)
896         {
897             register int i;
898             xkb->names->keycodes = xkb_intern_atom(info.name);
899             for (i = info.computedMin; i <= info.computedMax; i++)
900             {
901                 LongToKeyName(info.names[i], xkb->names->keys[i].name);
902             }
903         }
904         else
905         {
906             WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
907             return False;
908         }
909         if (info.leds)
910         {
911             IndicatorNameInfo *ii;
912             if (XkbcAllocIndicatorMaps(xkb) != Success)
913             {
914                 WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
915                 ACTION("Physical indicators not set\n");
916             }
917             for (ii = info.leds; ii != NULL;
918                  ii = (IndicatorNameInfo *) ii->defs.next)
919             {
920                 xkb->names->indicators[ii->ndx - 1] = ii->name;
921                 if (xkb->indicators != NULL)
922                 {
923                     register unsigned bit;
924                     bit = 1 << (ii->ndx - 1);
925                     if (ii->virtual)
926                         xkb->indicators->phys_indicators &= ~bit;
927                     else
928                         xkb->indicators->phys_indicators |= bit;
929                 }
930             }
931         }
932         if (info.aliases)
933             ApplyAliases(xkb, False, &info.aliases);
934         return True;
935     }
936     ClearKeyNamesInfo(&info);
937     return False;
938 }