about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Doc/Zsh/builtins.yo10
-rw-r--r--Src/builtin.c15
3 files changed, 28 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index b33d2f3a3..196b6a6cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2007-12-12  Peter Stephenson  <pws@csr.com>
 
+	* users/12325: Doc/Zsh/builtins.yo, Src/builtin.c:
+	implement OSI rules for three- and four-argument test and [ ... ]
+	commands and warn users about the problems.
+
 	* users/12305: Doc/Zsh/builtins.yo, Src/init.c,
 	Test/A01grammar.ztst: option output wasn't well described;
 	"-c" is documented not to set SHIN_STDIN, so don't.
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 204b29cf7..169f4f881 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -1235,7 +1235,15 @@ tt(test) and tt([) builtins are:  these commands are not handled
 syntactically, so for example an empty variable expansion may cause an
 argument to be omitted; syntax errors cause status 2 to be returned instead
 of a shell error; and arithmetic operators expect integer arguments rather
-than arithemetic expressions.
+than arithmetic expressions.
+
+The command attempts to implement POSIX and its extensions where these
+are specified.  Unfortunately there are intrinsic ambiguities in
+the syntax; in particular there is no distinction between test operators
+and strings that resemble them.  The standard attempts to resolve these
+for small numbers of arguments (up to four); for five or more arguments
+compatibility cannot be relied on.  Users are urged wherever possible to
+use the `tt([[)' test syntax which does not have these ambiguities.
 )
 findex(times)
 cindex(shell, timing)
diff --git a/Src/builtin.c b/Src/builtin.c
index 2e0d249f3..7bd4c6d83 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -5506,6 +5506,7 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func)
     char **s;
     Eprog prog;
     struct estate state;
+    int nargs;
 
     /* if "test" was invoked as "[", it needs a matching "]" *
      * which is subsequently ignored                         */
@@ -5521,6 +5522,20 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func)
     if (!*argv)
 	return 1;
 
+    /*
+     * Implement some XSI extensions to POSIX here.
+     * See
+     * http://www.opengroup.org/onlinepubs/009695399/utilities/test.html.
+     */
+    nargs = arrlen(argv);
+    if (nargs == 3 || nargs == 4)
+    {
+	if (*argv[0] == '(' && *argv[nargs-1] == ')') {
+	    argv[nargs-1] = NULL;
+	    argv++;
+	}
+    }
+
     testargs = argv;
     tok = NULLTOK;
     condlex = testlex;