about summary refs log tree commit diff
path: root/Src/builtin.c
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2013-09-06 20:37:40 +0100
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2013-09-06 20:37:40 +0100
commitc866657a3cfd8a82d3c6ee06ff193a0c927b299f (patch)
tree035042b67d623a42acbeb2f9a0c75e6b9ace254b /Src/builtin.c
parent3573ab44e7a041f83dab1dc56ed0b77b8d18d996 (diff)
downloadzsh-c866657a3cfd8a82d3c6ee06ff193a0c927b299f.tar.gz
zsh-c866657a3cfd8a82d3c6ee06ff193a0c927b299f.tar.xz
zsh-c866657a3cfd8a82d3c6ee06ff193a0c927b299f.zip
31706: standardize handling of "test ! <x> <y> <z>"
Diffstat (limited to 'Src/builtin.c')
-rw-r--r--Src/builtin.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/Src/builtin.c b/Src/builtin.c
index f8be4acc9..c3f0169c7 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -5995,7 +5995,7 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func)
     char **s;
     Eprog prog;
     struct estate state;
-    int nargs;
+    int nargs, sense = 0, ret;
 
     /* if "test" was invoked as "[", it needs a matching "]" *
      * which is subsequently ignored                         */
@@ -6014,7 +6014,7 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func)
     /*
      * Implement some XSI extensions to POSIX here.
      * See
-     * http://www.opengroup.org/onlinepubs/009695399/utilities/test.html.
+     * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html
      */
     nargs = arrlen(argv);
     if (nargs == 3 || nargs == 4)
@@ -6023,6 +6023,10 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func)
 	    argv[nargs-1] = NULL;
 	    argv++;
 	}
+	if (nargs == 4 && !strcmp("!", argv[0])) {
+	    sense = 1;
+	    argv++;
+	}
     }
 
     lexsave();
@@ -6057,8 +6061,11 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func)
     state.pc = prog->prog;
     state.strs = prog->strs;
 
+    ret = evalcond(&state, name);
+    if (ret < 2 && sense)
+	ret = ! ret;
 
-    return evalcond(&state, name);
+    return ret;
 }
 
 /* display a time, provided in units of 1/60s, as minutes and seconds */