summary refs log tree commit diff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2014-09-28 18:40:18 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2014-09-28 18:40:18 +0800
commit4f7e4c8201e580b9d31c09d8a484741072033c01 (patch)
tree2ec700c405904ae054398ec76ebe1819ef49b898
parentRelease 0.5.8. (diff)
downloaddash-4f7e4c8201e580b9d31c09d8a484741072033c01.tar.gz
dash-4f7e4c8201e580b9d31c09d8a484741072033c01.zip
[BUILTIN] Correctly handle test ! ! = !
This patch adds a special case in testcmd for the 4-argument
expression beginning with a !.  Without this ! ! = ! is deemed
a syntax error, which breaks POSIX.

Note that this special case does not extend down into subexpressions
so if ! ! = ! is used inside parentheses then a syntax error will
still occur as before.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--ChangeLog4
-rw-r--r--src/bltin/test.c10
2 files changed, 11 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index a466a7f..7345144 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-09-28  Herbert Xu <herbert@gondor.apana.org.au>
+
+	* Correctly handle test ! ! = !.
+
 2014-09-26  Herbert Xu <herbert@gondor.apana.org.au>
 
 	* Small optimisation of command -pv change.
diff --git a/src/bltin/test.c b/src/bltin/test.c
index baa91a5..458e9f5 100644
--- a/src/bltin/test.c
+++ b/src/bltin/test.c
@@ -177,7 +177,7 @@ testcmd(int argc, char **argv)
 {
 	const struct t_op *op;
 	enum token n;
-	int res;
+	int res = 1;
 
 	if (*argv[0] == '[') {
 		if (*argv[--argc] != ']')
@@ -185,11 +185,12 @@ testcmd(int argc, char **argv)
 		argv[argc] = NULL;
 	}
 
+recheck:
 	argv++;
 	argc--;
 
 	if (argc < 1)
-		return 1;
+		return res;
 
 	/*
 	 * POSIX prescriptions: he who wrote this deserves the Nobel
@@ -209,6 +210,9 @@ testcmd(int argc, char **argv)
 			argv[--argc] = NULL;
 			argv++;
 			argc--;
+		} else if (!strcmp(argv[0], "!")) {
+			res = 0;
+			goto recheck;
 		}
 	}
 
@@ -216,7 +220,7 @@ testcmd(int argc, char **argv)
 
 eval:
 	t_wp = argv;
-	res = !oexpr(n);
+	res ^= oexpr(n);
 	argv = t_wp;
 
 	if (argv[0] != NULL && argv[1] != NULL)