registry: simplify strdup() error handling
[platform/upstream/libxkbcommon.git] / src / xkbcomp / symbols.c
index ce19715..f990529 100644 (file)
@@ -51,6 +51,8 @@
  *         Ran Benita <ran234@gmail.com>
  */
 
+#include "config.h"
+
 #include "xkbcomp-priv.h"
 #include "text.h"
 #include "expr.h"
@@ -160,6 +162,8 @@ ClearKeyInfo(KeyInfo *keyi)
 typedef struct {
     enum merge_mode merge;
     bool haveSymbol;
+    // NOTE: Can also be XKB_MOD_NONE, meaning
+    //       “don’t add a modifier to the modmap”.
     xkb_mod_index_t modifier;
     union {
         xkb_atom_t keyName;
@@ -227,6 +231,7 @@ MergeGroups(SymbolsInfo *info, GroupInfo *into, GroupInfo *from, bool clobber,
     /* First find the type of the merged group. */
     if (into->type != from->type) {
         if (from->type == XKB_ATOM_NONE) {
+            /* it's empty for consistency with other comparisons */
         }
         else if (into->type == XKB_ATOM_NONE) {
             into->type = from->type;
@@ -269,6 +274,7 @@ MergeGroups(SymbolsInfo *info, GroupInfo *into, GroupInfo *from, bool clobber,
         struct xkb_level *fromLevel = &darray_item(from->levels, i);
 
         if (fromLevel->action.type == ACTION_TYPE_NONE) {
+            /* it's empty for consistency with other comparisons */
         }
         else if (intoLevel->action.type == ACTION_TYPE_NONE) {
             intoLevel->action = fromLevel->action;
@@ -290,6 +296,7 @@ MergeGroups(SymbolsInfo *info, GroupInfo *into, GroupInfo *from, bool clobber,
         }
 
         if (fromLevel->num_syms == 0) {
+            /* it's empty for consistency with other comparisons */
         }
         else if (intoLevel->num_syms == 0) {
             intoLevel->num_syms = fromLevel->num_syms;
@@ -299,7 +306,7 @@ MergeGroups(SymbolsInfo *info, GroupInfo *into, GroupInfo *from, bool clobber,
                 intoLevel->u.sym = fromLevel->u.sym;
             fromLevel->num_syms = 0;
         }
-        else {
+        else if (!XkbLevelsSameSyms(fromLevel, intoLevel)) {
             if (report)
                 log_warn(info->ctx,
                          "Multiple symbols for level %d/group %u on key %s; "
@@ -458,19 +465,19 @@ AddModMapEntry(SymbolsInfo *info, ModMapEntry *new)
         ignore = (clobber ? old->modifier : new->modifier);
 
         if (new->haveSymbol)
-            log_err(info->ctx,
-                    "Symbol \"%s\" added to modifier map for multiple modifiers; "
-                    "Using %s, ignoring %s\n",
-                    KeysymText(info->ctx, new->u.keySym),
-                    ModIndexText(info->ctx, &info->mods, use),
-                    ModIndexText(info->ctx, &info->mods, ignore));
+            log_warn(info->ctx,
+                     "Symbol \"%s\" added to modifier map for multiple modifiers; "
+                     "Using %s, ignoring %s\n",
+                     KeysymText(info->ctx, new->u.keySym),
+                     ModIndexText(info->ctx, &info->mods, use),
+                     ModIndexText(info->ctx, &info->mods, ignore));
         else
-            log_err(info->ctx,
-                    "Key \"%s\" added to modifier map for multiple modifiers; "
-                    "Using %s, ignoring %s\n",
-                    KeyNameText(info->ctx, new->u.keyName),
-                    ModIndexText(info->ctx, &info->mods, use),
-                    ModIndexText(info->ctx, &info->mods, ignore));
+            log_warn(info->ctx,
+                     "Key \"%s\" added to modifier map for multiple modifiers; "
+                     "Using %s, ignoring %s\n",
+                     KeyNameText(info->ctx, new->u.keyName),
+                     ModIndexText(info->ctx, &info->mods, use),
+                     ModIndexText(info->ctx, &info->mods, ignore));
 
         old->modifier = use;
         return true;
@@ -486,8 +493,6 @@ static void
 MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
                      enum merge_mode merge)
 {
-    KeyInfo *keyi;
-    ModMapEntry *mm;
     xkb_atom_t *group_name;
     xkb_layout_index_t group_names_in_both;
 
@@ -523,6 +528,7 @@ MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
         darray_init(from->keys);
     }
     else {
+        KeyInfo *keyi;
         darray_foreach(keyi, from->keys) {
             keyi->merge = (merge == MERGE_DEFAULT ? keyi->merge : merge);
             if (!AddKeySymbols(into, keyi, false))
@@ -535,6 +541,7 @@ MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
         darray_init(from->modmaps);
     }
     else {
+        ModMapEntry *mm;
         darray_foreach(mm, from->modmaps) {
             mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge);
             if (!AddModMapEntry(into, mm))
@@ -750,7 +757,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
     }
 
     nActs = 0;
-    for (act = value->unary.child; act; act = (ExprDef *) act->common.next)
+    for (act = value->actions.actions; act; act = (ExprDef *) act->common.next)
         nActs++;
 
     if (darray_size(groupi->levels) < nActs)
@@ -758,7 +765,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
 
     groupi->defined |= GROUP_FIELD_ACTS;
 
-    act = value->unary.child;
+    act = value->actions.actions;
     for (unsigned i = 0; i < nActs; i++) {
         union xkb_action *toAct = &darray_item(groupi->levels, i).action;
 
@@ -1147,14 +1154,21 @@ HandleModMapDef(SymbolsInfo *info, ModMapDef *def)
     xkb_mod_index_t ndx;
     bool ok;
     struct xkb_context *ctx = info->ctx;
-
-    ndx = XkbModNameToIndex(&info->mods, def->modifier, MOD_REAL);
-    if (ndx == XKB_MOD_INVALID) {
-        log_err(info->ctx,
-                "Illegal modifier map definition; "
-                "Ignoring map for non-modifier \"%s\"\n",
-                xkb_atom_text(ctx, def->modifier));
-        return false;
+    const char *modifier_name = xkb_atom_text(ctx, def->modifier);
+
+    if (istreq(modifier_name, "none")) {
+        // Handle special "None" entry
+        ndx = XKB_MOD_NONE;
+    } else {
+        // Handle normal entry
+        ndx = XkbModNameToIndex(&info->mods, def->modifier, MOD_REAL);
+        if (ndx == XKB_MOD_INVALID) {
+            log_err(info->ctx,
+                    "Illegal modifier map definition; "
+                    "Ignoring map for non-modifier \"%s\"\n",
+                    xkb_atom_text(ctx, def->modifier));
+            return false;
+        }
     }
 
     ok = true;
@@ -1224,7 +1238,7 @@ HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge)
 
         if (info->errorCount > 10) {
             log_err(info->ctx, "Abandoning symbols file \"%s\"\n",
-                    file->topName);
+                    file->name);
             break;
         }
     }
@@ -1243,38 +1257,31 @@ HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge)
 static struct xkb_key *
 FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym)
 {
-    struct xkb_key *key, *ret = NULL;
-    xkb_layout_index_t group, min_group = UINT32_MAX;
-    xkb_level_index_t level, min_level = UINT16_MAX;
-
-    xkb_keys_foreach(key, keymap) {
-        for (group = 0; group < key->num_groups; group++) {
-            for (level = 0; level < XkbKeyGroupWidth(key, group); level++) {
-                if (key->groups[group].levels[level].num_syms != 1 ||
-                    key->groups[group].levels[level].u.sym != sym)
-                    continue;
-
-                /*
-                 * If the keysym was found in a group or level > 0, we must
-                 * keep looking since we might find a key in which the keysym
-                 * is in a lower group or level.
-                 */
-                if (group < min_group ||
-                    (group == min_group && level < min_level)) {
-                    ret = key;
-                    if (group == 0 && level == 0) {
-                        return ret;
-                    }
-                    else {
-                        min_group = group;
-                        min_level = level;
-                    }
+    struct xkb_key *key;
+    xkb_layout_index_t group;
+    bool got_one_group, got_one_level;
+
+    group = 0;
+    do {
+        xkb_level_index_t level = 0;
+        got_one_group = false;
+        do {
+            got_one_level = false;
+            xkb_keys_foreach(key, keymap) {
+                if (group < key->num_groups &&
+                    level < XkbKeyNumLevels(key, group)) {
+                    got_one_group = got_one_level = true;
+                    if (key->groups[group].levels[level].num_syms == 1 &&
+                        key->groups[group].levels[level].u.sym == sym)
+                        return key;
                 }
             }
-        }
-    }
+            level++;
+        } while (got_one_level);
+        group++;
+    } while (got_one_group);
 
-    return ret;
+    return NULL;
 }
 
 /*
@@ -1292,8 +1299,8 @@ FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym)
 static xkb_atom_t
 FindAutomaticType(struct xkb_context *ctx, GroupInfo *groupi)
 {
-    xkb_keysym_t sym0, sym1, sym2, sym3;
-    xkb_level_index_t width = darray_size(groupi->levels);
+    xkb_keysym_t sym0, sym1;
+    const xkb_level_index_t width = darray_size(groupi->levels);
 
 #define GET_SYM(level) \
     (darray_item(groupi->levels, level).num_syms == 0 ? \
@@ -1321,6 +1328,7 @@ FindAutomaticType(struct xkb_context *ctx, GroupInfo *groupi)
 
     if (width <= 4) {
         if (xkb_keysym_is_lower(sym0) && xkb_keysym_is_upper(sym1)) {
+            xkb_keysym_t sym2, sym3;
             sym2 = GET_SYM(2);
             sym3 = (width == 4 ? GET_SYM(3) : XKB_KEY_NoSymbol);
 
@@ -1524,7 +1532,12 @@ CopyModMapDefToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info,
         }
     }
 
-    key->modmap |= (1u << entry->modifier);
+    // Handle modMap None
+    if (entry->modifier != XKB_MOD_NONE) {
+        // Convert modifier index to modifier mask
+        key->modmap |= (1u << entry->modifier);
+    }
+
     return true;
 }