test: fix mishandling of 'test ! arg1 op arg2 more args'; add testsuite
This commit is contained in:
parent
6d52c1ee24
commit
1e2a7e4ed1
@ -555,7 +555,7 @@ int test_main(int argc, char **argv)
|
||||
{
|
||||
int res;
|
||||
const char *arg0;
|
||||
bool _off;
|
||||
bool negate = 0;
|
||||
|
||||
arg0 = bb_basename(argv[0]);
|
||||
if (arg0[0] == '[') {
|
||||
@ -578,9 +578,8 @@ int test_main(int argc, char **argv)
|
||||
INIT_S();
|
||||
|
||||
res = setjmp(leaving);
|
||||
if (res) {
|
||||
if (res)
|
||||
goto ret;
|
||||
}
|
||||
|
||||
/* resetting ngroups is probably unnecessary. it will
|
||||
* force a new call to getgroups(), which prevents using
|
||||
@ -592,34 +591,40 @@ int test_main(int argc, char **argv)
|
||||
*/
|
||||
ngroups = 0;
|
||||
|
||||
//argc--;
|
||||
argv++;
|
||||
|
||||
/* Implement special cases from POSIX.2, section 4.62.4 */
|
||||
if (argc == 1) {
|
||||
if (!argv[0]) { /* "test" */
|
||||
res = 1;
|
||||
goto ret;
|
||||
}
|
||||
if (argc == 2) {
|
||||
res = (*argv[1] == '\0');
|
||||
if (LONE_CHAR(argv[0], '!') && argv[1]) {
|
||||
negate = 1;
|
||||
//argc--;
|
||||
argv++;
|
||||
}
|
||||
if (!argv[1]) { /* "test [!] arg" */
|
||||
res = (*argv[0] == '\0');
|
||||
goto ret;
|
||||
}
|
||||
|
||||
/* remember if we saw argc==4 which wants *no* '!' test */
|
||||
_off = argc - 4;
|
||||
if (_off ? (LONE_CHAR(argv[1], '!'))
|
||||
: (argv[1][0] != '!' || argv[1][1] != '\0')
|
||||
) {
|
||||
if (argc == 3) {
|
||||
res = (*argv[2] != '\0');
|
||||
goto ret;
|
||||
}
|
||||
|
||||
t_lex(argv[2 + _off]);
|
||||
if (argv[2] && !argv[3]) {
|
||||
t_lex(argv[1]);
|
||||
if (t_wp_op && t_wp_op->op_type == BINOP) {
|
||||
t_wp = &argv[1 + _off];
|
||||
res = (binop() == _off);
|
||||
/* "test [!] arg1 <binary_op> arg2" */
|
||||
t_wp = &argv[0];
|
||||
res = (binop() == 0);
|
||||
goto ret;
|
||||
}
|
||||
}
|
||||
t_wp = &argv[1];
|
||||
|
||||
/* Some complex expression. Undo '!' removal */
|
||||
if (negate) {
|
||||
negate = 0;
|
||||
//argc++;
|
||||
argv--;
|
||||
}
|
||||
t_wp = &argv[0];
|
||||
res = !oexpr(t_lex(*t_wp));
|
||||
|
||||
if (*t_wp != NULL && *++t_wp != NULL) {
|
||||
@ -628,5 +633,5 @@ int test_main(int argc, char **argv)
|
||||
}
|
||||
ret:
|
||||
DEINIT_S();
|
||||
return res;
|
||||
return negate ? !res : res;
|
||||
}
|
||||
|
26
testsuite/test.tests
Executable file
26
testsuite/test.tests
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright 2007 by Denys Vlasenko <vda.linux@googlemail.com>
|
||||
# Licensed under GPL v2, see file LICENSE for details.
|
||||
|
||||
. testing.sh
|
||||
|
||||
# testing "test name" "options" "expected result" "file input" "stdin"
|
||||
# file input will be file called "input"
|
||||
# test can create a file "actual" instead of writing to stdout
|
||||
|
||||
# Need to call 'busybox test', otherwise shell builtin is used
|
||||
|
||||
testing "test ! a = b -a ! c = c: should be false" \
|
||||
"busybox test ! a = b -a ! c = c; echo \$?" \
|
||||
"1\n" \
|
||||
"" \
|
||||
"" \
|
||||
|
||||
testing "test ! a = b -a ! c = d: should be true" \
|
||||
"busybox test ! a = b -a ! c = d; echo \$?" \
|
||||
"0\n" \
|
||||
"" \
|
||||
"" \
|
||||
|
||||
exit $FAILCOUNT
|
Loading…
Reference in New Issue
Block a user