]> git.sur5r.net Git - i3/i3/commitdiff
new parser: correctly handle leading/trailing newlines (+test) (Thanks helgikrs)
authorMichael Stapelberg <michael@stapelberg.de>
Wed, 25 Jan 2012 22:00:32 +0000 (22:00 +0000)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 25 Jan 2012 22:00:32 +0000 (22:00 +0000)
src/commands_parser.c
testcases/t/187-commands-parser.t

index af0afe02a69b80cb13d3eb0d50e2dc30661333ac..1bb9f0c2ba8ac5fb65a77af0ecaa6c1d2453729c 100644 (file)
@@ -214,8 +214,9 @@ char *parse_command(const char *input) {
     /* The "<=" operator is intentional: We also handle the terminating 0-byte
      * explicitly by looking for an 'end' token. */
     while ((walk - input) <= len) {
-        /* skip whitespace before every token */
-        while ((*walk == ' ' || *walk == '\t') && *walk != '\0')
+        /* skip whitespace and newlines before every token */
+        while ((*walk == ' ' || *walk == '\t' ||
+                *walk == '\r' || *walk == '\n') && *walk != '\0')
             walk++;
 
         DLOG("remaining input = %s\n", walk);
@@ -255,15 +256,20 @@ char *parse_command(const char *input) {
                     if (token->name[0] == 's') {
                         /* For a string (starting with 's'), the delimiters are
                          * comma (,) and semicolon (;) which introduce a new
-                         * operation or command, respectively. */
-                        while (*walk != ';' && *walk != ',' && *walk != '\0')
+                         * operation or command, respectively. Also, newlines
+                         * end a command. */
+                        while (*walk != ';' && *walk != ',' &&
+                               *walk != '\0' && *walk != '\r' &&
+                               *walk != '\n')
                             walk++;
                     } else {
                         /* For a word, the delimiters are white space (' ' or
                          * '\t'), closing square bracket (]), comma (,) and
                          * semicolon (;). */
-                        while (*walk != ' ' && *walk != '\t' && *walk != ']' &&
-                               *walk != ',' && *walk !=  ';' && *walk != '\0')
+                        while (*walk != ' ' && *walk != '\t' &&
+                               *walk != ']' && *walk != ',' &&
+                               *walk !=  ';' && *walk != '\r' &&
+                               *walk != '\n' && *walk != '\0')
                             walk++;
                     }
                 }
@@ -382,8 +388,8 @@ void debuglog(uint64_t lev, char *fmt, ...) {
     va_list args;
 
     va_start(args, fmt);
-    fprintf(stdout, "# ");
-    vfprintf(stdout, fmt, args);
+    fprintf(stderr, "# ");
+    vfprintf(stderr, fmt, args);
     va_end(args);
 }
 
index 35eaef7308bb4a3365e449005979d20bd9066fce..1a11068b782ce805c7a65c048655a5b5daf82e4d 100644 (file)
@@ -12,7 +12,7 @@ sub parser_calls {
 
     # TODO: use a timeout, so that we can error out if it doesn’t terminate
     # TODO: better way of passing arguments
-    my $stdout = qx(../test.commands_parser '$command');
+    my $stdout = qx(../test.commands_parser '$command' 2>&-);
 
     # Filter out all debugging output.
     my @lines = split("\n", $stdout);
@@ -129,6 +129,17 @@ is(parser_calls('[con_mark="yay"] focus'),
    "cmd_focus()",
    'quoted criteria focus ok');
 
+# Make sure trailing whitespace is stripped off: While this is not an issue for
+# commands being parsed due to the configuration, people might send IPC
+# commands with leading or trailing newlines.
+is(parser_calls("workspace test\n"),
+   'cmd_workspace_name(test)',
+   'trailing whitespace stripped off ok');
+
+is(parser_calls("\nworkspace test"),
+   'cmd_workspace_name(test)',
+   'trailing whitespace stripped off ok');
+
 ################################################################################
 # 2: Verify that the parser spits out the right error message on commands which
 # are not ok.