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