diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-31 19:20:43 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-31 19:21:51 +0200 |
commit | 78b1b1b07ac2784f67bc65bb1d86cc2559a12446 (patch) | |
tree | d2cd92f90441ad5799381cec6a27f6ac88100cdc | |
parent | cee603d921594fc779bc26a200dfb010cd62ab92 (diff) | |
download | busybox-w32-78b1b1b07ac2784f67bc65bb1d86cc2559a12446.tar.gz busybox-w32-78b1b1b07ac2784f67bc65bb1d86cc2559a12446.tar.bz2 busybox-w32-78b1b1b07ac2784f67bc65bb1d86cc2559a12446.zip |
test: fix 4-argument case
Upstream dash commit:
Date: Sun, 13 Jul 2008 19:20:10 +0800
Fixed 3,4-argument cases for test per POSIX
----- Forwarded message from Gerrit Pape <pape@smarden.org> -----
Subject: Bug#455828: dash: 4-argument test "test \( ! -e \)" yields an error
Date: Fri, 28 Dec 2007 08:53:29 +0000
From: Gerrit Pape <pape@smarden.org>
To: Vincent Lefevre <vincent@vinc17.org>, 455828@bugs.debian.org
On Thu, Dec 27, 2007 at 06:23:20PM +0100, Vincent Lefevre wrote:
> On 2007-12-27 16:00:06 +0000, Gerrit Pape wrote:
> > On Wed, Dec 12, 2007 at 02:18:47AM +0100, Vincent Lefevre wrote:
> > > According to POSIX[*], "test \( ! -e \)" is a 4-argument test and is
> > > here equivalent to "test ! -e". But dash (like ksh93 and bash) yields
> > > an error:
> > >
> > > $ test \( ! -e \) || echo $?
> > > test: 1: closing paren expected
> > > 2
> > > $ test ! -e || echo $?
> > > 1
> >
> > Hi Vincent,
> >
> > the -e switch to test takes an argument, a pathname.
>
> According to POSIX, in both above examples, "-e" is *not* a switch,
> just a string.
>
> test \( ! -e \)
>
> means: return true if the string "-e" is empty, otherwhise return false.
> The error in dash is that it incorrectly thinks that "-e" is a switch in
> this context.
I see, you're right. Thanks, Gerrit.
----- End forwarded message -----
This patch hard-codes the 3,4-argument cases in the way required by
POSIX.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function old new delta
test_main 370 421 +51
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | coreutils/test.c | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/coreutils/test.c b/coreutils/test.c index d8ac42e22..a8286525a 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -879,18 +879,48 @@ int test_main(int argc, char **argv) | |||
879 | res = (argv[0][0] == '\0'); | 879 | res = (argv[0][0] == '\0'); |
880 | goto ret_special; | 880 | goto ret_special; |
881 | } | 881 | } |
882 | if (argv[2] && !argv[3]) { | 882 | if (argv[2]) { |
883 | check_operator(argv[1]); | 883 | if (!argv[3]) { |
884 | if (last_operator->op_type == BINOP) { | 884 | /* |
885 | /* "test [!] arg1 <binary_op> arg2" */ | 885 | * http://pubs.opengroup.org/onlinepubs/009695399/utilities/test.html |
886 | args = argv; | 886 | * """ 3 arguments: |
887 | res = (binop() == 0); | 887 | * If $2 is a binary primary, perform the binary test of $1 and $3. |
888 | * """ | ||
889 | */ | ||
890 | check_operator(argv[1]); | ||
891 | if (last_operator->op_type == BINOP) { | ||
892 | /* "test [!] arg1 <binary_op> arg2" */ | ||
893 | args = argv; | ||
894 | res = (binop() == 0); | ||
888 | ret_special: | 895 | ret_special: |
889 | /* If there was leading "!" op... */ | 896 | /* If there was leading "!" op... */ |
890 | res ^= negate; | 897 | res ^= negate; |
891 | goto ret; | 898 | goto ret; |
899 | } | ||
900 | /* """If $1 is '(' and $3 is ')', perform the unary test of $2.""" | ||
901 | * Looks like this works without additional coding. | ||
902 | */ | ||
903 | goto check_negate; | ||
904 | } | ||
905 | /* argv[3] exists (at least 4 args), is it exactly 4 args? */ | ||
906 | if (!argv[4]) { | ||
907 | /* | ||
908 | * """ 4 arguments: | ||
909 | * If $1 is '!', negate the three-argument test of $2, $3, and $4. | ||
910 | * If $1 is '(' and $4 is ')', perform the two-argument test of $2 and $3. | ||
911 | * """ | ||
912 | * Example why code below is necessary: test '(' ! -e ')' | ||
913 | */ | ||
914 | if (LONE_CHAR(argv[0], '(') | ||
915 | && LONE_CHAR(argv[3], ')') | ||
916 | ) { | ||
917 | /* "test [!] ( x y )" */ | ||
918 | argv[3] = NULL; | ||
919 | argv++; | ||
920 | } | ||
892 | } | 921 | } |
893 | } | 922 | } |
923 | check_negate: | ||
894 | if (LONE_CHAR(argv[0], '!')) { | 924 | if (LONE_CHAR(argv[0], '!')) { |
895 | argv++; | 925 | argv++; |
896 | negate ^= 1; | 926 | negate ^= 1; |