dump: a few more tweaks to match xkbcomp output
[platform/upstream/libxkbcommon.git] / src / xkbcomp / keycodes.c
index 9892024..5186432 100644 (file)
 
  ********************************************************/
 
-#include "xkbcomp.h"
-#include "xkballoc.h"
-#include "xkbmisc.h"
-#include "tokens.h"
-#include "expr.h"
 #include "keycodes.h"
-#include "misc.h"
+#include "expr.h"
+#include "parseutils.h"
 #include "alias.h"
 
-char *
+const char *
 longText(unsigned long val)
 {
     char buf[4];
@@ -51,7 +47,6 @@ LongToKeyName(unsigned long val, char *name)
     name[1] = ((val >> 16) & 0xff);
     name[2] = ((val >> 8) & 0xff);
     name[3] = (val & 0xff);
-    return;
 }
 
 /***====================================================================***/
@@ -60,8 +55,8 @@ typedef struct _IndicatorNameInfo
 {
     CommonInfo defs;
     int ndx;
-    uint32_t name;
-    Bool virtual;
+    xkb_atom_t name;
+    bool virtual;
 } IndicatorNameInfo;
 
 typedef struct _KeyNamesInfo
@@ -69,24 +64,31 @@ typedef struct _KeyNamesInfo
     char *name;     /* e.g. evdev+aliases(qwerty) */
     int errorCount;
     unsigned fileID;
-    unsigned merge;
-    int computedMin; /* lowest keycode stored */
-    int computedMax; /* highest keycode stored */
-    int explicitMin;
-    int explicitMax;
-    int effectiveMin;
-    int effectiveMax;
-    unsigned long names[XkbMaxLegalKeyCode + 1]; /* 4-letter name of key, keycode is the index */
-    unsigned files[XkbMaxLegalKeyCode + 1];
-    unsigned char has_alt_forms[XkbMaxLegalKeyCode + 1];
+    enum merge_mode merge;
+    xkb_keycode_t computedMin; /* lowest keycode stored */
+    xkb_keycode_t computedMax; /* highest keycode stored */
+    xkb_keycode_t explicitMin;
+    xkb_keycode_t explicitMax;
+    darray(unsigned long) names;
+    darray(unsigned int) files;
+    darray(unsigned char) has_alt_forms;
     IndicatorNameInfo *leds;
     AliasInfo *aliases;
 } KeyNamesInfo;
 
-static void HandleKeycodesFile(XkbFile * file,
-                               struct xkb_desc * xkb,
-                               unsigned merge,
-                               KeyNamesInfo * info);
+static void HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
+                               enum merge_mode merge, KeyNamesInfo *info);
+
+static void
+ResizeKeyNameArrays(KeyNamesInfo *info, int newMax)
+{
+    if (newMax < darray_size(info->names))
+        return;
+
+    darray_resize0(info->names, newMax + 1);
+    darray_resize0(info->files, newMax + 1);
+    darray_resize0(info->has_alt_forms, newMax + 1);
+}
 
 static void
 InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
@@ -96,9 +98,8 @@ InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
     ii->defs.fileID = info->fileID;
     ii->defs.next = NULL;
     ii->ndx = 0;
-    ii->name = None;
-    ii->virtual = False;
-    return;
+    ii->name = XKB_ATOM_NONE;
+    ii->virtual = false;
 }
 
 static void
@@ -109,7 +110,6 @@ ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
         ClearCommonInfo(&ii->defs);
         info->leds = NULL;
     }
-    return;
 }
 
 static IndicatorNameInfo *
@@ -121,8 +121,7 @@ NextIndicatorName(KeyNamesInfo * info)
     if (ii)
     {
         InitIndicatorNameInfo(ii, info);
-        info->leds = (IndicatorNameInfo *) AddCommonInfo(&info->leds->defs,
-                                                         (CommonInfo *) ii);
+        info->leds = AddCommonInfo(&info->leds->defs, &ii->defs);
     }
     return ii;
 }
@@ -142,7 +141,7 @@ FindIndicatorByIndex(KeyNamesInfo * info, int ndx)
 }
 
 static IndicatorNameInfo *
-FindIndicatorByName(KeyNamesInfo * info, uint32_t name)
+FindIndicatorByName(KeyNamesInfo * info, xkb_atom_t name)
 {
     IndicatorNameInfo *old;
 
@@ -155,21 +154,22 @@ FindIndicatorByName(KeyNamesInfo * info, uint32_t name)
     return NULL;
 }
 
-static Bool
-AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
+static bool
+AddIndicatorName(KeyNamesInfo *info, struct xkb_keymap *keymap, enum merge_mode merge,
+                 IndicatorNameInfo *new)
 {
     IndicatorNameInfo *old;
-    Bool replace;
+    bool replace;
 
-    replace = (new->defs.merge == MergeReplace) ||
-        (new->defs.merge == MergeOverride);
+    replace = (merge == MERGE_REPLACE) || (merge == MERGE_OVERRIDE);
     old = FindIndicatorByName(info, new->name);
     if (old)
     {
         if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
             || (warningLevel > 9))
         {
-            WARN("Multiple indicators named %s\n", XkbcAtomText(new->name));
+            WARN("Multiple indicators named %s\n",
+                 xkb_atom_text(keymap->ctx, new->name));
             if (old->ndx == new->ndx)
             {
                 if (old->virtual != new->virtual)
@@ -184,7 +184,7 @@ AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
                 {
                     ACTION("Identical definitions ignored\n");
                 }
-                return True;
+                return true;
             }
             else
             {
@@ -227,7 +227,7 @@ AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
             else
             {
                 const char *oldType, *newType;
-                uint32_t using, ignoring;
+                xkb_atom_t using, ignoring;
                 if (old->virtual)
                     oldType = "virtual indicator";
                 else
@@ -247,8 +247,8 @@ AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
                     ignoring = new->name;
                 }
                 ACTION("Using %s %s, ignoring %s %s\n",
-                        oldType, XkbcAtomText(using),
-                        newType, XkbcAtomText(ignoring));
+                        oldType, xkb_atom_text(keymap->ctx, using),
+                        newType, xkb_atom_text(keymap->ctx, ignoring));
             }
         }
         if (replace)
@@ -256,40 +256,36 @@ AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
             old->name = new->name;
             old->virtual = new->virtual;
         }
-        return True;
+        return true;
     }
     old = new;
     new = NextIndicatorName(info);
     if (!new)
     {
-        WSGO("Couldn't allocate name for indicator %d\n", new->ndx);
+        WSGO("Couldn't allocate name for indicator %d\n", old->ndx);
         ACTION("Ignored\n");
-        return False;
+        return false;
     }
     new->name = old->name;
     new->ndx = old->ndx;
     new->virtual = old->virtual;
-    return True;
+    return true;
 }
 
 static void
 ClearKeyNamesInfo(KeyNamesInfo * info)
 {
-    if (info->name != NULL)
-        free(info->name);
+    free(info->name);
     info->name = NULL;
-    info->computedMax = info->explicitMax = info->explicitMin = -1;
-    info->computedMin = 256;
-    info->effectiveMin = 8;
-    info->effectiveMax = 255;
-    bzero((char *) info->names, sizeof(info->names));
-    bzero((char *) info->files, sizeof(info->files));
-    bzero((char *) info->has_alt_forms, sizeof(info->has_alt_forms));
+    info->computedMax = info->explicitMax = info->explicitMin = 0;
+    info->computedMin = XKB_KEYCODE_MAX;
+    darray_free(info->names);
+    darray_free(info->files);
+    darray_free(info->has_alt_forms);
     if (info->leds)
         ClearIndicatorNameInfo(info->leds, info);
     if (info->aliases)
         ClearAliases(&info->aliases);
-    return;
 }
 
 static void
@@ -298,21 +294,22 @@ InitKeyNamesInfo(KeyNamesInfo * info)
     info->name = NULL;
     info->leds = NULL;
     info->aliases = NULL;
+    darray_init(info->names);
+    darray_init(info->files);
+    darray_init(info->has_alt_forms);
     ClearKeyNamesInfo(info);
     info->errorCount = 0;
-    return;
 }
 
 static int
 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
 {
-    register int i;
+    uint64_t i;
 
-    for (i = info->effectiveMin; i <= info->effectiveMax; i++)
-    {
-        if (info->names[i] == name)
+    for (i = info->computedMin; i <= info->computedMax; i++)
+        if (darray_item(info->names, i) == name)
             return i;
-    }
+
     return 0;
 }
 
@@ -321,21 +318,16 @@ FindKeyByLong(KeyNamesInfo * info, unsigned long name)
  * keycode. If the same keys is referred to twice, print a warning.
  * Note that the key's name is stored as a long, the keycode is the index.
  */
-static Bool
+static bool
 AddKeyName(KeyNamesInfo * info,
-           int kc,
-           char *name, unsigned merge, unsigned fileID, Bool reportCollisions)
+           xkb_keycode_t kc,
+           char *name, enum merge_mode merge, unsigned fileID, bool reportCollisions)
 {
-    int old;
+    xkb_keycode_t old;
     unsigned long lval;
 
-    if ((kc < info->effectiveMin) || (kc > info->effectiveMax))
-    {
-        ERROR("Illegal keycode %d for name <%s>\n", kc, name);
-        ACTION("Must be in the range %d-%d inclusive\n",
-                info->effectiveMin, info->effectiveMax);
-        return False;
-    }
+    ResizeKeyNameArrays(info, kc);
+
     if (kc < info->computedMin)
         info->computedMin = kc;
     if (kc > info->computedMax)
@@ -344,39 +336,37 @@ AddKeyName(KeyNamesInfo * info,
 
     if (reportCollisions)
     {
-        reportCollisions = ((warningLevel > 7) ||
-                            ((warningLevel > 0)
-                             && (fileID == info->files[kc])));
+        reportCollisions = (warningLevel > 7 ||
+                            (warningLevel > 0 &&
+                             fileID == darray_item(info->files, kc)));
     }
 
-    if (info->names[kc] != 0)
+    if (darray_item(info->names, kc) != 0)
     {
         char buf[6];
 
-        LongToKeyName(info->names[kc], buf);
+        LongToKeyName(darray_item(info->names, kc), buf);
         buf[4] = '\0';
-        if (info->names[kc] == lval)
+        if (darray_item(info->names, kc) == lval)
         {
-            if (info->has_alt_forms[kc] || (merge == MergeAltForm))
-            {
-                info->has_alt_forms[kc] = True;
+            if (darray_item(info->has_alt_forms, kc) || (merge == MERGE_ALT_FORM)) {
+                darray_item(info->has_alt_forms, kc) = true;
             }
-            else if (reportCollisions)
-            {
+            else if (reportCollisions) {
                 WARN("Multiple identical key name definitions\n");
                 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
                         buf, kc);
             }
-            return True;
+            return true;
         }
-        if (merge == MergeAugment)
+        if (merge == MERGE_AUGMENT)
         {
             if (reportCollisions)
             {
                 WARN("Multiple names for keycode %d\n", kc);
                 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
             }
-            return True;
+            return true;
         }
         else
         {
@@ -385,25 +375,25 @@ AddKeyName(KeyNamesInfo * info,
                 WARN("Multiple names for keycode %d\n", kc);
                 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
             }
-            info->names[kc] = 0;
-            info->files[kc] = 0;
+            darray_item(info->names, kc) = 0;
+            darray_item(info->files, kc) = 0;
         }
     }
     old = FindKeyByLong(info, lval);
     if ((old != 0) && (old != kc))
     {
-        if (merge == MergeOverride)
+        if (merge == MERGE_OVERRIDE)
         {
-            info->names[old] = 0;
-            info->files[old] = 0;
-            info->has_alt_forms[old] = True;
+            darray_item(info->names, old) = 0;
+            darray_item(info->files, old) = 0;
+            darray_item(info->has_alt_forms, old) = true;
             if (reportCollisions)
             {
                 WARN("Key name <%s> assigned to multiple keys\n", name);
                 ACTION("Using %d, ignoring %d\n", kc, old);
             }
         }
-        else if (merge != MergeAltForm)
+        else if (merge != MERGE_ALT_FORM)
         {
             if ((reportCollisions) && (warningLevel > 3))
             {
@@ -412,26 +402,26 @@ AddKeyName(KeyNamesInfo * info,
                 ACTION
                     ("Use 'alternate' keyword to assign the same name to multiple keys\n");
             }
-            return True;
+            return true;
         }
         else
         {
-            info->has_alt_forms[old] = True;
+            darray_item(info->has_alt_forms, old) = true;
         }
     }
-    info->names[kc] = lval;
-    info->files[kc] = fileID;
-    info->has_alt_forms[kc] = (merge == MergeAltForm);
-    return True;
+    darray_item(info->names, kc) = lval;
+    darray_item(info->files, kc) = fileID;
+    darray_item(info->has_alt_forms, kc) = (merge == MERGE_ALT_FORM);
+    return true;
 }
 
 /***====================================================================***/
 
 static void
-MergeIncludedKeycodes(KeyNamesInfo * into, KeyNamesInfo * from,
-                      unsigned merge)
+MergeIncludedKeycodes(KeyNamesInfo *into, struct xkb_keymap *keymap,
+                      KeyNamesInfo *from, enum merge_mode merge)
 {
-    register int i;
+    uint64_t i;
     char buf[5];
 
     if (from->errorCount > 0)
@@ -444,18 +434,21 @@ MergeIncludedKeycodes(KeyNamesInfo * into, KeyNamesInfo * from,
         into->name = from->name;
         from->name = NULL;
     }
+
+    ResizeKeyNameArrays(into, from->computedMax);
+
     for (i = from->computedMin; i <= from->computedMax; i++)
     {
         unsigned thisMerge;
-        if (from->names[i] == 0)
+        if (darray_item(from->names, i) == 0)
             continue;
-        LongToKeyName(from->names[i], buf);
+        LongToKeyName(darray_item(from->names, i), buf);
         buf[4] = '\0';
-        if (from->has_alt_forms[i])
-            thisMerge = MergeAltForm;
+        if (darray_item(from->has_alt_forms, i))
+            thisMerge = MERGE_ALT_FORM;
         else
             thisMerge = merge;
-        if (!AddKeyName(into, i, buf, thisMerge, from->fileID, False))
+        if (!AddKeyName(into, i, buf, thisMerge, from->fileID, false))
             into->errorCount++;
     }
     if (from->leds)
@@ -463,75 +456,78 @@ MergeIncludedKeycodes(KeyNamesInfo * into, KeyNamesInfo * from,
         IndicatorNameInfo *led, *next;
         for (led = from->leds; led != NULL; led = next)
         {
-            if (merge != MergeDefault)
+            if (merge != MERGE_DEFAULT)
                 led->defs.merge = merge;
-            if (!AddIndicatorName(into, led))
+            if (!AddIndicatorName(into, keymap, led->defs.merge, led))
                 into->errorCount++;
             next = (IndicatorNameInfo *) led->defs.next;
         }
     }
     if (!MergeAliases(&into->aliases, &from->aliases, merge))
         into->errorCount++;
-    if (from->explicitMin > 0)
+    if (from->explicitMin != 0)
     {
-        if ((into->explicitMin < 0)
+        if ((into->explicitMin == 0)
             || (into->explicitMin > from->explicitMin))
-            into->effectiveMin = into->explicitMin = from->explicitMin;
+            into->explicitMin = from->explicitMin;
     }
     if (from->explicitMax > 0)
     {
-        if ((into->explicitMax < 0)
+        if ((into->explicitMax == 0)
             || (into->explicitMax < from->explicitMax))
-            into->effectiveMax = into->explicitMax = from->explicitMax;
+            into->explicitMax = from->explicitMax;
     }
-    return;
 }
 
 /**
  * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
  *
  * @param stmt The include statement from the keymap file.
- * @param xkb Unused for all but the xkb->flags.
+ * @param keymap Unused for all but the keymap->flags.
  * @param info Struct to store the key info in.
  */
-static Bool
-HandleIncludeKeycodes(IncludeStmt * stmt, struct xkb_desc * xkb, KeyNamesInfo * info)
+static bool
+HandleIncludeKeycodes(IncludeStmt *stmt, struct xkb_keymap *keymap,
+                      KeyNamesInfo *info)
 {
     unsigned newMerge;
     XkbFile *rtrn;
-    KeyNamesInfo included = {NULL};
-    Bool haveSelf;
+    KeyNamesInfo included;
+    bool haveSelf;
 
-    haveSelf = False;
+    memset(&included, 0, sizeof(included));
+
+    haveSelf = false;
     if ((stmt->file == NULL) && (stmt->map == NULL))
     {
-        haveSelf = True;
+        haveSelf = true;
         included = *info;
-        bzero(info, sizeof(KeyNamesInfo));
+        memset(info, 0, sizeof(KeyNamesInfo));
     }
-    else if (strcmp(stmt->file, "computed") == 0)
+    else if (stmt->file && strcmp(stmt->file, "computed") == 0)
     {
-        xkb->flags |= AutoKeyNames;
-        info->explicitMin = XkbMinLegalKeyCode;
-        info->explicitMax = XkbMaxLegalKeyCode;
+        keymap->flags |= AutoKeyNames;
+        info->explicitMin = 0;
+        info->explicitMax = XKB_KEYCODE_MAX;
         return (info->errorCount == 0);
     } /* parse file, store returned info in the xkb struct */
-    else if (ProcessIncludeFile(stmt, XkmKeyNamesIndex, &rtrn, &newMerge))
+    else if (ProcessIncludeFile(keymap->ctx, stmt, FILE_TYPE_KEYCODES, &rtrn,
+                                &newMerge))
     {
         InitKeyNamesInfo(&included);
-        HandleKeycodesFile(rtrn, xkb, MergeOverride, &included);
+        HandleKeycodesFile(rtrn, keymap, MERGE_OVERRIDE, &included);
         if (stmt->stmt != NULL)
         {
-            if (included.name != NULL)
-                free(included.name);
+            free(included.name);
             included.name = stmt->stmt;
             stmt->stmt = NULL;
         }
+        FreeXKBFile(rtrn);
     }
     else
     {
         info->errorCount += 10; /* XXX: why 10?? */
-        return False;
+        return false;
     }
     /* Do we have more than one include statement? */
     if ((stmt->next != NULL) && (included.errorCount < 1))
@@ -544,21 +540,24 @@ HandleIncludeKeycodes(IncludeStmt * stmt, struct xkb_desc * xkb, KeyNamesInfo *
         {
             if ((next->file == NULL) && (next->map == NULL))
             {
-                haveSelf = True;
-                MergeIncludedKeycodes(&included, info, next->merge);
+                haveSelf = true;
+                MergeIncludedKeycodes(&included, keymap, info, next->merge);
                 ClearKeyNamesInfo(info);
             }
-            else if (ProcessIncludeFile(next, XkmKeyNamesIndex, &rtrn, &op))
+            else if (ProcessIncludeFile(keymap->ctx, next, FILE_TYPE_KEYCODES,
+                                        &rtrn, &op))
             {
                 InitKeyNamesInfo(&next_incl);
-                HandleKeycodesFile(rtrn, xkb, MergeOverride, &next_incl);
-                MergeIncludedKeycodes(&included, &next_incl, op);
+                HandleKeycodesFile(rtrn, keymap, MERGE_OVERRIDE, &next_incl);
+                MergeIncludedKeycodes(&included, keymap, &next_incl, op);
                 ClearKeyNamesInfo(&next_incl);
+                FreeXKBFile(rtrn);
             }
             else
             {
                 info->errorCount += 10; /* XXX: Why 10?? */
-                return False;
+                ClearKeyNamesInfo(&included);
+                return false;
             }
         }
     }
@@ -566,7 +565,7 @@ HandleIncludeKeycodes(IncludeStmt * stmt, struct xkb_desc * xkb, KeyNamesInfo *
         *info = included;
     else
     {
-        MergeIncludedKeycodes(info, &included, newMerge);
+        MergeIncludedKeycodes(info, keymap, &included, newMerge);
         ClearKeyNamesInfo(&included);
     }
     return (info->errorCount == 0);
@@ -577,32 +576,26 @@ HandleIncludeKeycodes(IncludeStmt * stmt, struct xkb_desc * xkb, KeyNamesInfo *
  * e.g. <ESC> = 9
  */
 static int
-HandleKeycodeDef(KeycodeDef * stmt, unsigned merge, KeyNamesInfo * info)
+HandleKeycodeDef(KeycodeDef *stmt, enum merge_mode merge, KeyNamesInfo *info)
 {
-    int code;
-    ExprResult result;
-
-    if (!ExprResolveInteger(stmt->value, &result, NULL, NULL))
+    if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
+        (info->explicitMax != 0 && stmt->value > info->explicitMax))
     {
-        ACTION("No value keycode assigned to name <%s>\n", stmt->name);
-        return 0;
-    }
-    code = result.ival;
-    if ((code < info->effectiveMin) || (code > info->effectiveMax))
-    {
-        ERROR("Illegal keycode %d for name <%s>\n", code, stmt->name);
+        ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
         ACTION("Must be in the range %d-%d inclusive\n",
-                info->effectiveMin, info->effectiveMax);
+                info->explicitMin,
+                info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
         return 0;
     }
-    if (stmt->merge != MergeDefault)
+    if (stmt->merge != MERGE_DEFAULT)
     {
-        if (stmt->merge == MergeReplace)
-            merge = MergeOverride;
+        if (stmt->merge == MERGE_REPLACE)
+            merge = MERGE_OVERRIDE;
         else
             merge = stmt->merge;
     }
-    return AddKeyName(info, code, stmt->name, merge, info->fileID, True);
+    return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
+                      true);
 }
 
 #define        MIN_KEYCODE_DEF         0
@@ -610,103 +603,107 @@ HandleKeycodeDef(KeycodeDef * stmt, unsigned merge, KeyNamesInfo * info)
 
 /**
  * Handle the minimum/maximum statement of the xkb file.
- * Sets explicitMin/Max and effectiveMin/Max of the info struct.
+ * Sets explicitMin/Max of the info struct.
  *
  * @return 1 on success, 0 otherwise.
  */
 static int
-HandleKeyNameVar(VarDef * stmt, KeyNamesInfo * info)
+HandleKeyNameVar(VarDef *stmt, struct xkb_keymap *keymap, KeyNamesInfo *info)
 {
     ExprResult tmp, field;
     ExprDef *arrayNdx;
     int which;
 
-    if (ExprResolveLhs(stmt->name, &tmp, &field, &arrayNdx) == 0)
+    if (ExprResolveLhs(keymap, stmt->name, &tmp, &field, &arrayNdx) == 0)
         return 0;               /* internal error, already reported */
 
     if (tmp.str != NULL)
     {
         ERROR("Unknown element %s encountered\n", tmp.str);
         ACTION("Default for field %s ignored\n", field.str);
-        return 0;
+        goto err_out;
     }
-    if (uStrCaseCmp(field.str, "minimum") == 0)
+    if (strcasecmp(field.str, "minimum") == 0)
         which = MIN_KEYCODE_DEF;
-    else if (uStrCaseCmp(field.str, "maximum") == 0)
+    else if (strcasecmp(field.str, "maximum") == 0)
         which = MAX_KEYCODE_DEF;
     else
     {
         ERROR("Unknown field encountered\n");
         ACTION("Assigment to field %s ignored\n", field.str);
-        return 0;
+        goto err_out;
     }
     if (arrayNdx != NULL)
     {
         ERROR("The %s setting is not an array\n", field.str);
         ACTION("Illegal array reference ignored\n");
-        return 0;
+        goto err_out;
     }
 
-    if (ExprResolveInteger(stmt->value, &tmp, NULL, NULL) == 0)
+    if (ExprResolveKeyCode(keymap->ctx, stmt->value, &tmp) == 0)
     {
         ACTION("Assignment to field %s ignored\n", field.str);
-        return 0;
+        goto err_out;
     }
-    if ((tmp.ival < XkbMinLegalKeyCode) || (tmp.ival > XkbMaxLegalKeyCode))
+    if (tmp.uval > XKB_KEYCODE_MAX)
     {
         ERROR
             ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
-             tmp.ival, XkbMinLegalKeyCode, XkbMaxLegalKeyCode);
+             tmp.uval, 0, XKB_KEYCODE_MAX);
         ACTION("Value of \"%s\" not changed\n", field.str);
-        return 0;
+        goto err_out;
     }
     if (which == MIN_KEYCODE_DEF)
     {
-        if ((info->explicitMax > 0) && (info->explicitMax < tmp.ival))
+        if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
         {
             ERROR
                 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
-                 tmp.ival, info->explicitMax);
+                 tmp.uval, info->explicitMax);
             ACTION("Minimum key code value not changed\n");
-            return 0;
+            goto err_out;
         }
-        if ((info->computedMax > 0) && (info->computedMin < tmp.ival))
+        if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
         {
             ERROR
                 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
-                 tmp.ival, info->computedMin);
+                 tmp.uval, info->computedMin);
             ACTION("Minimum key code value not changed\n");
-            return 0;
+            goto err_out;
         }
-        info->explicitMin = tmp.ival;
-        info->effectiveMin = tmp.ival;
+        info->explicitMin = tmp.uval;
     }
     if (which == MAX_KEYCODE_DEF)
     {
-        if ((info->explicitMin > 0) && (info->explicitMin > tmp.ival))
+        if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
         {
             ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
-                   tmp.ival, info->explicitMin);
+                   tmp.uval, info->explicitMin);
             ACTION("Maximum code value not changed\n");
-            return 0;
+            goto err_out;
         }
-        if ((info->computedMax > 0) && (info->computedMax > tmp.ival))
+        if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
         {
             ERROR
                 ("Maximum code (%d) must be >= highest defined key (%d)\n",
-                 tmp.ival, info->computedMax);
+                 tmp.uval, info->computedMax);
             ACTION("Maximum code value not changed\n");
-            return 0;
+            goto err_out;
         }
-        info->explicitMax = tmp.ival;
-        info->effectiveMax = tmp.ival;
+        info->explicitMax = tmp.uval;
     }
+
+    free(field.str);
     return 1;
+
+err_out:
+    free(field.str);
+    return 0;
 }
 
 static int
-HandleIndicatorNameDef(IndicatorNameDef * def,
-                       unsigned merge, KeyNamesInfo * info)
+HandleIndicatorNameDef(IndicatorNameDef *def, struct xkb_keymap *keymap,
+                       enum merge_mode merge, KeyNamesInfo *info)
 {
     IndicatorNameInfo ii;
     ExprResult tmp;
@@ -716,23 +713,23 @@ HandleIndicatorNameDef(IndicatorNameDef * def,
         info->errorCount++;
         ERROR("Name specified for illegal indicator index %d\n", def->ndx);
         ACTION("Ignored\n");
-        return False;
+        return false;
     }
     InitIndicatorNameInfo(&ii, info);
     ii.ndx = def->ndx;
-    if (!ExprResolveString(def->name, &tmp, NULL, NULL))
+    if (!ExprResolveString(keymap->ctx, def->name, &tmp))
     {
         char buf[20];
         snprintf(buf, sizeof(buf), "%d", def->ndx);
         info->errorCount++;
         return ReportBadType("indicator", "name", buf, "string");
     }
-    ii.name = xkb_intern_atom(tmp.str);
+    ii.name = xkb_atom_intern(keymap->ctx, tmp.str);
     free(tmp.str);
     ii.virtual = def->virtual;
-    if (!AddIndicatorName(info, &ii))
-        return False;
-    return True;
+    if (!AddIndicatorName(info, keymap, merge, &ii))
+        return false;
+    return true;
 }
 
 /**
@@ -745,23 +742,24 @@ HandleIndicatorNameDef(IndicatorNameDef * def,
  *
  * @param file The input file (parsed xkb_keycodes section)
  * @param xkb Necessary to pass down, may have flags changed.
- * @param merge Merge strategy (MergeOverride, etc.)
+ * @param merge Merge strategy (MERGE_OVERRIDE, etc.)
  * @param info Struct to contain the fully parsed key information.
  */
 static void
-HandleKeycodesFile(XkbFile * file,
-                   struct xkb_desc * xkb, unsigned merge, KeyNamesInfo * info)
+HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
+                   enum merge_mode merge, KeyNamesInfo *info)
 {
     ParseCommon *stmt;
 
-    info->name = _XkbDupString(file->name);
+    free(info->name);
+    info->name = uDupString(file->name);
     stmt = file->defs;
     while (stmt)
     {
         switch (stmt->stmtType)
         {
         case StmtInclude:    /* e.g. include "evdev+aliases(qwerty)" */
-            if (!HandleIncludeKeycodes((IncludeStmt *) stmt, xkb, info))
+            if (!HandleIncludeKeycodes((IncludeStmt *) stmt, keymap, info))
                 info->errorCount++;
             break;
         case StmtKeycodeDef: /* e.g. <ESC> = 9; */
@@ -769,20 +767,18 @@ HandleKeycodesFile(XkbFile * file,
                 info->errorCount++;
             break;
         case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
-            if (!HandleAliasDef((KeyAliasDef *) stmt,
-                                merge, info->fileID, &info->aliases))
+            if (!HandleAliasDef((KeyAliasDef *) stmt, merge, info->fileID,
+                                &info->aliases))
                 info->errorCount++;
             break;
         case StmtVarDef: /* e.g. minimum, maximum */
-            if (!HandleKeyNameVar((VarDef *) stmt, info))
+            if (!HandleKeyNameVar((VarDef *) stmt, keymap, info))
                 info->errorCount++;
             break;
         case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
-            if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt,
+            if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt, keymap,
                                         merge, info))
-            {
                 info->errorCount++;
-            }
             break;
         case StmtInterpDef:
         case StmtVModDef:
@@ -808,7 +804,6 @@ HandleKeycodesFile(XkbFile * file,
             break;
         }
     }
-    return;
 }
 
 /**
@@ -819,70 +814,63 @@ HandleKeycodesFile(XkbFile * file,
  * @param result The effective keycodes, as gathered from the file.
  * @param merge Merge strategy.
  *
- * @return True on success, False otherwise.
+ * @return true on success, false otherwise.
  */
-Bool
-CompileKeycodes(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
+bool
+CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
 {
     KeyNamesInfo info; /* contains all the info after parsing */
 
     InitKeyNamesInfo(&info);
-    HandleKeycodesFile(file, xkb, merge, &info);
+
+    HandleKeycodesFile(file, keymap, merge, &info);
 
     /* all the keys are now stored in info */
 
-    if (info.errorCount == 0)
-    {
-        if (info.explicitMin > 0) /* if "minimum" statement was present */
-            xkb->min_key_code = info.effectiveMin;
-        else
-            xkb->min_key_code = info.computedMin;
-        if (info.explicitMax > 0) /* if "maximum" statement was present */
-            xkb->max_key_code = info.effectiveMax;
-        else
-            xkb->max_key_code = info.computedMax;
-        if (XkbcAllocNames(xkb, XkbKeyNamesMask | XkbIndicatorNamesMask, 0, 0)
-                == Success)
-        {
-            register int i;
-            xkb->names->keycodes = xkb_intern_atom(info.name);
-            for (i = info.computedMin; i <= info.computedMax; i++)
-            {
-                LongToKeyName(info.names[i], xkb->names->keys[i].name);
-            }
-        }
-        else
-        {
-            WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
-            return False;
+    if (info.errorCount != 0)
+        goto err_info;
+
+    if (info.explicitMin > 0) /* if "minimum" statement was present */
+        keymap->min_key_code = info.explicitMin;
+    else
+        keymap->min_key_code = info.computedMin;
+
+    if (info.explicitMax > 0) /* if "maximum" statement was present */
+        keymap->max_key_code = info.explicitMax;
+    else
+        keymap->max_key_code = info.computedMax;
+
+    if (XkbcAllocNames(keymap, XkbKeyNamesMask | XkbIndicatorNamesMask, 0)
+        == Success) {
+        uint64_t i;
+        for (i = info.computedMin; i <= info.computedMax; i++)
+            LongToKeyName(darray_item(info.names, i),
+                          darray_item(keymap->names->keys, i).name);
+    } else {
+        WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
+        goto err_info;
+    }
+
+    if (info.leds) {
+        IndicatorNameInfo *ii;
+        if (XkbcAllocIndicatorMaps(keymap) != Success) {
+            WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
+            ACTION("Physical indicators not set\n");
         }
-        if (info.leds)
-        {
-            IndicatorNameInfo *ii;
-            if (XkbcAllocIndicatorMaps(xkb) != Success)
-            {
-                WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
-                ACTION("Physical indicators not set\n");
-            }
-            for (ii = info.leds; ii != NULL;
-                 ii = (IndicatorNameInfo *) ii->defs.next)
-            {
-                xkb->names->indicators[ii->ndx - 1] = ii->name;
-                if (xkb->indicators != NULL)
-                {
-                    register unsigned bit;
-                    bit = 1 << (ii->ndx - 1);
-                    if (ii->virtual)
-                        xkb->indicators->phys_indicators &= ~bit;
-                    else
-                        xkb->indicators->phys_indicators |= bit;
-                }
-            }
+
+        for (ii = info.leds; ii; ii = (IndicatorNameInfo *)ii->defs.next) {
+            free(keymap->names->indicators[ii->ndx - 1]);
+            keymap->names->indicators[ii->ndx - 1] =
+                xkb_atom_strdup(keymap->ctx, ii->name);
         }
-        if (info.aliases)
-            ApplyAliases(xkb, False, &info.aliases);
-        return True;
     }
+
+    ApplyAliases(keymap, &info.aliases);
+
+    ClearKeyNamesInfo(&info);
+    return true;
+
+err_info:
     ClearKeyNamesInfo(&info);
-    return False;
+    return false;
 }