diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Doc/Zsh/builtins.yo | 10 | ||||
-rw-r--r-- | Src/builtin.c | 15 |
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; |