mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-30 00:20:44 +09:00
cmd_test: implement ! on sub-expressions
Currently, ! can only be parsed as the first operator in an expression. This prevents the following from working: $ if test ! ! 1 -eq 1; then echo yes; else echo no; fi yes $ if test ! 1 -eq 2 -a ! 3 -eq 4; then echo yes; else echo no; fi yes Fix this by parsing ! like any other operator, and and handling it similarly to -a and -o. Signed-off-by: Stephen Warren <swarren@nvidia.com>
This commit is contained in:
parent
4c80f29edd
commit
d9b651ce31
@ -18,6 +18,7 @@
|
|||||||
#include <command.h>
|
#include <command.h>
|
||||||
|
|
||||||
#define OP_INVALID 0
|
#define OP_INVALID 0
|
||||||
|
#define OP_NOT 1
|
||||||
#define OP_OR 2
|
#define OP_OR 2
|
||||||
#define OP_AND 3
|
#define OP_AND 3
|
||||||
#define OP_STR_EMPTY 4
|
#define OP_STR_EMPTY 4
|
||||||
@ -49,6 +50,7 @@ const struct {
|
|||||||
{1, "-le", OP_INT_LE, 3},
|
{1, "-le", OP_INT_LE, 3},
|
||||||
{1, "-gt", OP_INT_GT, 3},
|
{1, "-gt", OP_INT_GT, 3},
|
||||||
{1, "-ge", OP_INT_GE, 3},
|
{1, "-ge", OP_INT_GE, 3},
|
||||||
|
{0, "!", OP_NOT, 1},
|
||||||
{0, "-o", OP_OR, 1},
|
{0, "-o", OP_OR, 1},
|
||||||
{0, "-a", OP_AND, 1},
|
{0, "-a", OP_AND, 1},
|
||||||
{0, "-z", OP_STR_EMPTY, 2},
|
{0, "-z", OP_STR_EMPTY, 2},
|
||||||
@ -58,7 +60,7 @@ const struct {
|
|||||||
static int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
static int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
char * const *ap;
|
char * const *ap;
|
||||||
int i, op, left, adv, expr, last_expr, neg, last_cmp;
|
int i, op, left, adv, expr, last_expr, last_unop, last_binop;
|
||||||
|
|
||||||
/* args? */
|
/* args? */
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
@ -73,17 +75,11 @@ static int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
last_expr = 0;
|
left = argc - 1;
|
||||||
left = argc - 1; ap = argv + 1;
|
ap = argv + 1;
|
||||||
if (left > 0 && strcmp(ap[0], "!") == 0) {
|
|
||||||
neg = 1;
|
|
||||||
ap++;
|
|
||||||
left--;
|
|
||||||
} else
|
|
||||||
neg = 0;
|
|
||||||
|
|
||||||
expr = -1;
|
expr = -1;
|
||||||
last_cmp = OP_INVALID;
|
last_unop = OP_INVALID;
|
||||||
|
last_binop = OP_INVALID;
|
||||||
last_expr = -1;
|
last_expr = -1;
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
for (i = 0; i < ARRAY_SIZE(op_adv); i++) {
|
for (i = 0; i < ARRAY_SIZE(op_adv); i++) {
|
||||||
@ -152,27 +148,36 @@ static int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
switch (op) {
|
switch (op) {
|
||||||
case OP_OR:
|
case OP_OR:
|
||||||
last_expr = expr;
|
last_expr = expr;
|
||||||
last_cmp = OP_OR;
|
last_binop = OP_OR;
|
||||||
break;
|
break;
|
||||||
case OP_AND:
|
case OP_AND:
|
||||||
last_expr = expr;
|
last_expr = expr;
|
||||||
last_cmp = OP_AND;
|
last_binop = OP_AND;
|
||||||
|
break;
|
||||||
|
case OP_NOT:
|
||||||
|
if (last_unop == OP_NOT)
|
||||||
|
last_unop = OP_INVALID;
|
||||||
|
else
|
||||||
|
last_unop = OP_NOT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (last_cmp == OP_OR)
|
if (last_unop == OP_NOT) {
|
||||||
|
expr = !expr;
|
||||||
|
last_unop = OP_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_binop == OP_OR)
|
||||||
expr = last_expr || expr;
|
expr = last_expr || expr;
|
||||||
else if (last_cmp == OP_AND)
|
else if (last_binop == OP_AND)
|
||||||
expr = last_expr && expr;
|
expr = last_expr && expr;
|
||||||
last_cmp = OP_INVALID;
|
last_binop = OP_INVALID;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ap += adv; left -= adv;
|
ap += adv; left -= adv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (neg)
|
|
||||||
expr = !expr;
|
|
||||||
|
|
||||||
expr = !expr;
|
expr = !expr;
|
||||||
|
|
||||||
debug (": returns %d\n", expr);
|
debug (": returns %d\n", expr);
|
||||||
|
Loading…
Reference in New Issue
Block a user