]> git.sur5r.net Git - i3/i3/commitdiff
cfg_workspace: Accept outputs with spaces again 3655/head
authorOrestis Floros <orestisf1993@gmail.com>
Thu, 21 Mar 2019 17:29:56 +0000 (19:29 +0200)
committerOrestis Floros <orestisf1993@gmail.com>
Thu, 21 Mar 2019 19:31:30 +0000 (21:31 +0200)
This is a regression from bce088679.

An other way to fix this would be to concatenate strings inside the
strtok loop when an output starts with a double quote but I'd rather
let the parser do the word splitting.

Fixes #3646

parser-specs/config.spec
src/config_directives.c
testcases/t/201-config-parser.t
testcases/t/297-assign-workspace-to-output.t

index 43181c59e1bb96f52563e5063e719daa9a7848fe..a256d8b0b48414403da6b7d73980fb53efa5afce 100644 (file)
@@ -277,11 +277,13 @@ state WORKSPACE:
 
 state WORKSPACE_OUTPUT:
   'output'
-      -> WORKSPACE_OUTPUT_STR
+      -> WORKSPACE_OUTPUT_WORD
 
-state WORKSPACE_OUTPUT_STR:
-  output = string
-      -> call cfg_workspace($workspace, $output)
+state WORKSPACE_OUTPUT_WORD:
+  output = word
+      -> call cfg_workspace($workspace, $output); WORKSPACE_OUTPUT_WORD
+  end
+      -> INITIAL
 
 # ipc-socket <path>
 state IPC_SOCKET:
index 7ca6954c555032303061e8e4177d4d227aac6c99..fb3fba415ae55200fc89f53da5dd5cf71610aeef 100644 (file)
@@ -334,30 +334,41 @@ CFGFUN(show_marks, const char *value) {
     config.show_marks = eval_boolstr(value);
 }
 
-CFGFUN(workspace, const char *workspace, const char *outputs) {
-    DLOG("Assigning workspace \"%s\" to outputs \"%s\"\n", workspace, outputs);
-    /* Check for earlier assignments of the same workspace so that we
-     * don’t have assignments of a single workspace to different
-     * outputs */
+static char *current_workspace = NULL;
+
+CFGFUN(workspace, const char *workspace, const char *output) {
     struct Workspace_Assignment *assignment;
-    TAILQ_FOREACH(assignment, &ws_assignments, ws_assignments) {
-        if (strcasecmp(assignment->name, workspace) == 0) {
-            ELOG("You have a duplicate workspace assignment for workspace \"%s\"\n",
-                 workspace);
+
+    /* When a new workspace line is encountered, for the first output word,
+     * $workspace from the config.spec is non-NULL. Afterwards, the parser calls
+     * clear_stack() because of the call line. Thus, we have to preserve the
+     * workspace string. */
+    if (workspace) {
+        FREE(current_workspace);
+
+        TAILQ_FOREACH(assignment, &ws_assignments, ws_assignments) {
+            if (strcasecmp(assignment->name, workspace) == 0) {
+                ELOG("You have a duplicate workspace assignment for workspace \"%s\"\n",
+                     workspace);
+                return;
+            }
+        }
+
+        current_workspace = sstrdup(workspace);
+    } else {
+        if (!current_workspace) {
+            DLOG("Both workspace and current_workspace are NULL, assuming we had an error before\n");
             return;
         }
+        workspace = current_workspace;
     }
 
-    char *buf = sstrdup(outputs);
-    char *output = strtok(buf, " ");
-    while (output != NULL) {
-        assignment = scalloc(1, sizeof(struct Workspace_Assignment));
-        assignment->name = sstrdup(workspace);
-        assignment->output = sstrdup(output);
-        TAILQ_INSERT_TAIL(&ws_assignments, assignment, ws_assignments);
-        output = strtok(NULL, " ");
-    }
-    free(buf);
+    DLOG("Assigning workspace \"%s\" to output \"%s\"\n", workspace, output);
+
+    assignment = scalloc(1, sizeof(struct Workspace_Assignment));
+    assignment->name = sstrdup(workspace);
+    assignment->output = sstrdup(output);
+    TAILQ_INSERT_TAIL(&ws_assignments, assignment, ws_assignments);
 }
 
 CFGFUN(ipc_socket, const char *path) {
index c6ce22eb9582eeaa35e1402c72d3ad3fb5c76377..65997bc775e4891613fec2284f5efd2bfb0f3cc5 100644 (file)
@@ -400,12 +400,18 @@ $config = <<'EOT';
 workspace 3 output VGA-1
 workspace "4: output" output VGA-2
 workspace bleh output LVDS1/I_1
+# See #3646
+workspace foo output a b c "a b c"
 EOT
 
 $expected = <<'EOT';
 cfg_workspace(3, VGA-1)
 cfg_workspace(4: output, VGA-2)
 cfg_workspace(bleh, LVDS1/I_1)
+cfg_workspace(foo, a)
+cfg_workspace((null), b)
+cfg_workspace((null), c)
+cfg_workspace((null), a b c)
 EOT
 
 is(parser_calls($config),
index a7b75be9fdfa5a49987c63cb22b6448a547d82a5..eb8f24b2f096748e42f1c4b27923a22719f6f367 100644 (file)
@@ -79,7 +79,9 @@ workspace 1 output fake-1 fake-2
 workspace 2 output fake-3 fake-4 fake-0 fake-1
 workspace 3 output these outputs do not exist but these do: fake-0 fake-3
 workspace 4 output whitespace                    fake-0
-workspace special output doesnotexist1 doesnotexist2 doesnotexist3
+workspace foo output doesnotexist1 doesnotexist2 doesnotexist3
+workspace bar output doesnotexist
+workspace bar output fake-0
 EOT
 
 $pid = launch_with_config($config);
@@ -91,8 +93,11 @@ do_test('4', 'fake-0', 'Excessive whitespace is ok');
 do_test('5', 'fake-1', 'Numbered initialization for fake-1');
 do_test('6', 'fake-2', 'Numbered initialization for fake-2');
 
-cmd 'focus output fake-0, workspace special';
-check_output('special', 'fake-0', 'Workspace with only non-existing assigned outputs opened in current output.');
+cmd 'focus output fake-0, workspace foo';
+check_output('foo', 'fake-0', 'Workspace with only non-existing assigned outputs opened in current output');
+
+cmd 'focus output fake-0, workspace bar';
+check_output('bar', 'fake-0', 'Second workspace assignment line ignored');
 
 # Moving assigned workspaces.
 cmd 'workspace 2, move workspace to output left';