]> git.sur5r.net Git - i3/i3/blobdiff - src/cfgparse.y
Merge branch 'master' into next
[i3/i3] / src / cfgparse.y
index ae5a7a736105a61346c2f5ad4e50ac3930c1521f..68173757589f50e90e666751bfd59391e2bfea16 100644 (file)
@@ -317,29 +317,44 @@ void kill_configerror_nagbar(bool wait_for_it) {
  * i3-nagbar.
  *
  */
-static bool check_for_duplicate_bindings(struct context *context) {
-    bool retval = true;
+static void check_for_duplicate_bindings(struct context *context) {
     Binding *bind, *current;
     TAILQ_FOREACH(current, bindings, bindings) {
-        bind = TAILQ_FIRST(bindings);
-        /* test only bindings visited up to current binding */
-        while ((bind != TAILQ_END(bindings)) && (bind != current)) {
-            /* testing is not case sensitive */
-            if ((strcasecmp(bind->symbol, current->symbol) == 0) &&
-                (bind->keycode == current->keycode) &&
-                (bind->mods == current->mods)) {
-                context->has_errors = true;
-                fprintf(stderr, "Duplicated keybinding in config file:  mod%d with key %s", current->mods, current->symbol);
-                /* if keycode is 0, this is a keysym binding */
-                if (current->keycode != 0)
-                    fprintf(stderr, " and keycode %d", current->keycode);
-                fprintf(stderr, "\n");
-                retval = false;
+        TAILQ_FOREACH(bind, bindings, bindings) {
+            /* Abort when we reach the current keybinding, only check the
+             * bindings before */
+            if (bind == current)
+                break;
+
+            /* Check if one is using keysym while the other is using bindsym.
+             * If so, skip. */
+            /* XXX: It should be checked at a later place (when translating the
+             * keysym to keycodes) if there are any duplicates */
+            if ((bind->symbol == NULL && current->symbol != NULL) ||
+                (bind->symbol != NULL && current->symbol == NULL))
+                continue;
+
+            /* If bind is NULL, current has to be NULL, too (see above).
+             * If the keycodes differ, it can't be a duplicate. */
+            if (bind->symbol != NULL &&
+                strcasecmp(bind->symbol, current->symbol) != 0)
+                continue;
+
+            /* Check if the keycodes or modifiers are different. If so, they
+             * can't be duplicate */
+            if (bind->keycode != current->keycode ||
+                bind->mods != current->mods)
+                continue;
+            context->has_errors = true;
+            if (current->keycode != 0) {
+                ELOG("Duplicate keybinding in config file:\n  modmask %d with keycode %d, command \"%s\"\n",
+                     current->mods, current->keycode, current->command);
+            } else {
+                ELOG("Duplicate keybinding in config file:\n  modmask %d with keysym %s, command \"%s\"\n",
+                     current->mods, current->symbol, current->command);
             }
-            bind = TAILQ_NEXT(bind, bindings);
         }
     }
-    return retval;
 }
 
 void parse_file(const char *f) {
@@ -1135,6 +1150,7 @@ colorpixel:
         char *hex;
         if (asprintf(&hex, "#%s", $2) == -1)
             die("asprintf()");
+        free($2);
         $$ = get_colorpixel(hex);
         free(hex);
     }