dump: a few more tweaks to match xkbcomp output
[platform/upstream/libxkbcommon.git] / src / xkbcomp / keymap.c
index 6c236a6..2904310 100644 (file)
 
  ********************************************************/
 
-#include "xkbcomp.h"
-#include "xkbmisc.h"
-#include "expr.h"
-#include "vmod.h"
-#include "action.h"
-#include "misc.h"
+#include "xkbcomp-priv.h"
 #include "indicators.h"
 
 /**
  * Compile the given file and store the output in xkb.
  * @param file A list of XkbFiles, each denoting one type (e.g.
- * XkmKeyNamesIdx, etc.)
+ * FILE_TYPE_KEYCODES, etc.)
  */
-Bool
-CompileKeymap(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
+struct xkb_keymap *
+CompileKeymap(struct xkb_context *ctx, XkbFile *file)
 {
-    unsigned have;
-    Bool ok;
-    unsigned required, legal;
-    unsigned mainType;
-    char *mainName;
-    LEDInfo *unbound = NULL;
+    unsigned have = 0;
+    bool ok;
+    enum xkb_file_type mainType;
+    const char *mainName;
+    struct xkb_keymap *keymap = XkbcAllocKeyboard(ctx);
     struct {
         XkbFile *keycodes;
         XkbFile *types;
         XkbFile *compat;
         XkbFile *symbols;
-    } sections;
+    } sections = { NULL };
+
+    if (!keymap)
+        return NULL;
 
-    memset(&sections, 0, sizeof(sections));
     mainType = file->type;
-    mainName = file->name;
-    switch (mainType)
-    {
-    case XkmSemanticsFile:
-        required = XkmSemanticsRequired;
-        legal = XkmSemanticsLegal;
-        break;
-    case XkmLayoutFile:        /* standard type  if setxkbmap -print */
-        required = XkmLayoutRequired;
-        legal = XkmKeymapLegal;
-        break;
-    case XkmKeymapFile:
-        required = XkmKeymapRequired;
-        legal = XkmKeymapLegal;
-        break;
-    default:
-        ERROR("Cannot compile %s alone into an XKM file\n",
-               XkbcConfigText(mainType));
-        return False;
+    mainName = file->name ? file->name : "(unnamed)";
+
+    /*
+     * Other aggregate file types are converted to FILE_TYPE_KEYMAP
+     * in the parser.
+     */
+    if (mainType != FILE_TYPE_KEYMAP) {
+        ERROR("Cannot compile a %s file alone into a keymap\n",
+              XkbcFileTypeText(mainType));
+        goto err;
     }
-    have = 0;
-    ok = 1;
-    file = (XkbFile *) file->defs;
+
     /* Check for duplicate entries in the input file */
-    while ((file) && (ok))
+    for (file = (XkbFile *) file->defs; file; file = (XkbFile *) file->common.next)
     {
-        if (file->topName != mainName) {
-            free(file->topName);
-            file->topName = strdup(mainName);
-        }
-        if ((have & (1 << file->type)) != 0)
-        {
+        if (have & file->type) {
             ERROR("More than one %s section in a %s file\n",
-                   XkbcConfigText(file->type), XkbcConfigText(mainType));
+                   XkbcFileTypeText(file->type), XkbcFileTypeText(mainType));
             ACTION("All sections after the first ignored\n");
-            ok = False;
+            continue;
         }
-        else if ((1 << file->type) & (~legal))
-        {
+        else if (!(file->type & LEGAL_FILE_TYPES)) {
             ERROR("Cannot define %s in a %s file\n",
-                   XkbcConfigText(file->type), XkbcConfigText(mainType));
-            ok = False;
+                   XkbcFileTypeText(file->type), XkbcFileTypeText(mainType));
+            continue;
+        }
+
+        switch (file->type) {
+        case FILE_TYPE_KEYCODES:
+            sections.keycodes = file;
+            break;
+        case FILE_TYPE_TYPES:
+            sections.types = file;
+            break;
+        case FILE_TYPE_SYMBOLS:
+            sections.symbols = file;
+            break;
+        case FILE_TYPE_COMPAT:
+            sections.compat = file;
+            break;
+        case FILE_TYPE_GEOMETRY:
+            continue;
+        default:
+            WSGO("Unknown file type %d\n", file->type);
+            ACTION("Ignored\n");
+            continue;
         }
-        else
-            switch (file->type)
-            {
-            case XkmSemanticsFile:
-            case XkmLayoutFile:
-            case XkmKeymapFile:
-                WSGO("Illegal %s configuration in a %s file\n",
-                      XkbcConfigText(file->type), XkbcConfigText(mainType));
-                ACTION("Ignored\n");
-                ok = False;
-                break;
-            case XkmKeyNamesIndex:
-                sections.keycodes = file;
-                break;
-            case XkmTypesIndex:
-                sections.types = file;
-                break;
-            case XkmSymbolsIndex:
-                sections.symbols = file;
-                break;
-            case XkmCompatMapIndex:
-                sections.compat = file;
-                break;
-            case XkmGeometryIndex:
-                /* XXX free me! */
-                break;
-            case XkmVirtualModsIndex:
-            case XkmIndicatorsIndex:
-                WSGO("Found an isolated %s section\n",
-                      XkbcConfigText(file->type));
-                break;
-            default:
-                WSGO("Unknown file type %d\n", file->type);
-                break;
+
+        if (!file->topName || strcmp(file->topName, mainName) != 0) {
+            free(file->topName);
+            file->topName = strdup(mainName);
+        }
+
+        have |= file->type;
+    }
+
+    if (REQUIRED_FILE_TYPES & (~have)) {
+        enum xkb_file_type bit;
+        enum xkb_file_type missing;
+
+        missing = REQUIRED_FILE_TYPES & (~have);
+
+        for (bit = 1; missing != 0; bit <<= 1) {
+            if (missing & bit) {
+                ERROR("Required section %s missing from keymap\n",
+                      XkbcFileTypeText(bit));
+                missing &= ~bit;
             }
-        if (ok)
-            have |= (1 << file->type);
-        file = (XkbFile *) file->common.next;
+        }
+
+        goto err;
     }
+
     /* compile the sections we have in the file one-by-one, or fail. */
-    if (ok)
+    if (sections.keycodes == NULL ||
+        !CompileKeycodes(sections.keycodes, keymap, MERGE_OVERRIDE))
     {
-        if (ok && (sections.keycodes != NULL))
-            ok = CompileKeycodes(sections.keycodes, xkb, MergeOverride);
-        if (ok && (sections.types != NULL))
-            ok = CompileKeyTypes(sections.types, xkb, MergeOverride);
-        if (ok && (sections.compat != NULL))
-            ok = CompileCompatMap(sections.compat, xkb, MergeOverride,
-                                  &unbound);
-        if (ok && (sections.symbols != NULL))
-            ok = CompileSymbols(sections.symbols, xkb, MergeOverride);
+        ERROR("Failed to compile keycodes\n");
+        goto err;
     }
-    if (!ok)
-        return False;
-    xkb->defined = have;
-    if (required & (~have))
+    if (sections.types == NULL ||
+        !CompileKeyTypes(sections.types, keymap, MERGE_OVERRIDE))
     {
-        int i, bit;
-        unsigned missing;
-        missing = required & (~have);
-        for (i = 0, bit = 1; missing != 0; i++, bit <<= 1)
-        {
-            if (missing & bit)
-            {
-                ERROR("Missing %s section in a %s file\n",
-                       XkbcConfigText(i), XkbcConfigText(mainType));
-                missing &= ~bit;
-            }
-        }
-        ACTION("Description of %s not compiled\n",
-                XkbcConfigText(mainType));
-        return False;
+        ERROR("Failed to compile key types\n");
+        goto err;
     }
-    ok = BindIndicators(xkb, True, unbound, NULL);
-    return ok;
+    if (sections.compat == NULL ||
+        !CompileCompatMap(sections.compat, keymap, MERGE_OVERRIDE))
+    {
+        ERROR("Failed to compile compat map\n");
+        goto err;
+    }
+    if (sections.symbols == NULL ||
+        !CompileSymbols(sections.symbols, keymap, MERGE_OVERRIDE))
+    {
+        ERROR("Failed to compile symbols\n");
+        goto err;
+    }
+
+    ok = UpdateModifiersFromCompat(keymap);
+    if (!ok)
+        goto err;
+
+    return keymap;
+
+err:
+    ACTION("Failed to compile keymap\n");
+    xkb_map_unref(keymap);
+    return NULL;
 }