diff options
author | Stephen Warren <swarren@nvidia.com> | 2014-02-03 13:21:04 -0700 |
---|---|---|
committer | jino.cho <jino.cho@samsung.com> | 2017-02-28 19:11:48 +0900 |
commit | 28eac7098e6f6c4268d45830dd02908df759efa6 (patch) | |
tree | 934b821261f74e3736217e8831b5083e8841dc7f | |
parent | 84aa0d91917faced19a6121f0b0c03387ba4bdf1 (diff) | |
download | u-boot-artik-28eac7098e6f6c4268d45830dd02908df759efa6.tar.gz u-boot-artik-28eac7098e6f6c4268d45830dd02908df759efa6.tar.bz2 u-boot-artik-28eac7098e6f6c4268d45830dd02908df759efa6.zip |
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>
-rw-r--r-- | common/cmd_test.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/common/cmd_test.c b/common/cmd_test.c index 540be99ca..0149d7edf 100644 --- a/common/cmd_test.c +++ b/common/cmd_test.c @@ -34,6 +34,7 @@ #include <command.h> #define OP_INVALID 0 +#define OP_NOT 1 #define OP_OR 2 #define OP_AND 3 #define OP_STR_EMPTY 4 @@ -65,6 +66,7 @@ const struct { {1, "-le", OP_INT_LE, 3}, {1, "-gt", OP_INT_GT, 3}, {1, "-ge", OP_INT_GE, 3}, + {0, "!", OP_NOT, 1}, {0, "-o", OP_OR, 1}, {0, "-a", OP_AND, 1}, {0, "-z", OP_STR_EMPTY, 2}, @@ -74,7 +76,7 @@ const struct { static int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { 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? */ if (argc < 3) @@ -89,17 +91,11 @@ static int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif - last_expr = 0; - left = argc - 1; ap = argv + 1; - if (left > 0 && strcmp(ap[0], "!") == 0) { - neg = 1; - ap++; - left--; - } else - neg = 0; - + left = argc - 1; + ap = argv + 1; expr = -1; - last_cmp = OP_INVALID; + last_unop = OP_INVALID; + last_binop = OP_INVALID; last_expr = -1; while (left > 0) { for (i = 0; i < ARRAY_SIZE(op_adv); i++) { @@ -168,27 +164,36 @@ static int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) switch (op) { case OP_OR: last_expr = expr; - last_cmp = OP_OR; + last_binop = OP_OR; break; case OP_AND: 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; 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; - else if (last_cmp == OP_AND) + else if (last_binop == OP_AND) expr = last_expr && expr; - last_cmp = OP_INVALID; + last_binop = OP_INVALID; + break; } ap += adv; left -= adv; } - if (neg) - expr = !expr; - expr = !expr; debug (": returns %d\n", expr); |