diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-09 05:48:42 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-09 05:48:42 +0000 |
commit | 1e2a7e4ed1ddcd457b6e7e3eebd6a90b7621079e (patch) | |
tree | 6949b702f7751c00b72bb24e1af7ca70c9f9c961 | |
parent | 6d52c1ee24f77690c932dfe8456dfa31e8808f4c (diff) | |
download | busybox-w32-1e2a7e4ed1ddcd457b6e7e3eebd6a90b7621079e.tar.gz busybox-w32-1e2a7e4ed1ddcd457b6e7e3eebd6a90b7621079e.tar.bz2 busybox-w32-1e2a7e4ed1ddcd457b6e7e3eebd6a90b7621079e.zip |
test: fix mishandling of 'test ! arg1 op arg2 more args'; add testsuite
-rw-r--r-- | coreutils/test.c | 49 | ||||
-rwxr-xr-x | testsuite/test.tests | 26 |
2 files changed, 53 insertions, 22 deletions
diff --git a/coreutils/test.c b/coreutils/test.c index a30a5087d..22dadac0e 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -555,7 +555,7 @@ int test_main(int argc, char **argv) | |||
555 | { | 555 | { |
556 | int res; | 556 | int res; |
557 | const char *arg0; | 557 | const char *arg0; |
558 | bool _off; | 558 | bool negate = 0; |
559 | 559 | ||
560 | arg0 = bb_basename(argv[0]); | 560 | arg0 = bb_basename(argv[0]); |
561 | if (arg0[0] == '[') { | 561 | if (arg0[0] == '[') { |
@@ -578,9 +578,8 @@ int test_main(int argc, char **argv) | |||
578 | INIT_S(); | 578 | INIT_S(); |
579 | 579 | ||
580 | res = setjmp(leaving); | 580 | res = setjmp(leaving); |
581 | if (res) { | 581 | if (res) |
582 | goto ret; | 582 | goto ret; |
583 | } | ||
584 | 583 | ||
585 | /* resetting ngroups is probably unnecessary. it will | 584 | /* resetting ngroups is probably unnecessary. it will |
586 | * force a new call to getgroups(), which prevents using | 585 | * force a new call to getgroups(), which prevents using |
@@ -592,34 +591,40 @@ int test_main(int argc, char **argv) | |||
592 | */ | 591 | */ |
593 | ngroups = 0; | 592 | ngroups = 0; |
594 | 593 | ||
594 | //argc--; | ||
595 | argv++; | ||
596 | |||
595 | /* Implement special cases from POSIX.2, section 4.62.4 */ | 597 | /* Implement special cases from POSIX.2, section 4.62.4 */ |
596 | if (argc == 1) { | 598 | if (!argv[0]) { /* "test" */ |
597 | res = 1; | 599 | res = 1; |
598 | goto ret; | 600 | goto ret; |
599 | } | 601 | } |
600 | if (argc == 2) { | 602 | if (LONE_CHAR(argv[0], '!') && argv[1]) { |
601 | res = (*argv[1] == '\0'); | 603 | negate = 1; |
604 | //argc--; | ||
605 | argv++; | ||
606 | } | ||
607 | if (!argv[1]) { /* "test [!] arg" */ | ||
608 | res = (*argv[0] == '\0'); | ||
602 | goto ret; | 609 | goto ret; |
603 | } | 610 | } |
604 | 611 | if (argv[2] && !argv[3]) { | |
605 | /* remember if we saw argc==4 which wants *no* '!' test */ | 612 | t_lex(argv[1]); |
606 | _off = argc - 4; | ||
607 | if (_off ? (LONE_CHAR(argv[1], '!')) | ||
608 | : (argv[1][0] != '!' || argv[1][1] != '\0') | ||
609 | ) { | ||
610 | if (argc == 3) { | ||
611 | res = (*argv[2] != '\0'); | ||
612 | goto ret; | ||
613 | } | ||
614 | |||
615 | t_lex(argv[2 + _off]); | ||
616 | if (t_wp_op && t_wp_op->op_type == BINOP) { | 613 | if (t_wp_op && t_wp_op->op_type == BINOP) { |
617 | t_wp = &argv[1 + _off]; | 614 | /* "test [!] arg1 <binary_op> arg2" */ |
618 | res = (binop() == _off); | 615 | t_wp = &argv[0]; |
616 | res = (binop() == 0); | ||
619 | goto ret; | 617 | goto ret; |
620 | } | 618 | } |
621 | } | 619 | } |
622 | t_wp = &argv[1]; | 620 | |
621 | /* Some complex expression. Undo '!' removal */ | ||
622 | if (negate) { | ||
623 | negate = 0; | ||
624 | //argc++; | ||
625 | argv--; | ||
626 | } | ||
627 | t_wp = &argv[0]; | ||
623 | res = !oexpr(t_lex(*t_wp)); | 628 | res = !oexpr(t_lex(*t_wp)); |
624 | 629 | ||
625 | if (*t_wp != NULL && *++t_wp != NULL) { | 630 | if (*t_wp != NULL && *++t_wp != NULL) { |
@@ -628,5 +633,5 @@ int test_main(int argc, char **argv) | |||
628 | } | 633 | } |
629 | ret: | 634 | ret: |
630 | DEINIT_S(); | 635 | DEINIT_S(); |
631 | return res; | 636 | return negate ? !res : res; |
632 | } | 637 | } |
diff --git a/testsuite/test.tests b/testsuite/test.tests new file mode 100755 index 000000000..351d35565 --- /dev/null +++ b/testsuite/test.tests | |||
@@ -0,0 +1,26 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # Copyright 2007 by Denys Vlasenko <vda.linux@googlemail.com> | ||
4 | # Licensed under GPL v2, see file LICENSE for details. | ||
5 | |||
6 | . testing.sh | ||
7 | |||
8 | # testing "test name" "options" "expected result" "file input" "stdin" | ||
9 | # file input will be file called "input" | ||
10 | # test can create a file "actual" instead of writing to stdout | ||
11 | |||
12 | # Need to call 'busybox test', otherwise shell builtin is used | ||
13 | |||
14 | testing "test ! a = b -a ! c = c: should be false" \ | ||
15 | "busybox test ! a = b -a ! c = c; echo \$?" \ | ||
16 | "1\n" \ | ||
17 | "" \ | ||
18 | "" \ | ||
19 | |||
20 | testing "test ! a = b -a ! c = d: should be true" \ | ||
21 | "busybox test ! a = b -a ! c = d; echo \$?" \ | ||
22 | "0\n" \ | ||
23 | "" \ | ||
24 | "" \ | ||
25 | |||
26 | exit $FAILCOUNT | ||