uboot/cmd/test.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2000-2009
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 */
   6
   7#include <common.h>
   8#include <command.h>
   9#include <fs.h>
  10#include <log.h>
  11
  12#define OP_INVALID      0
  13#define OP_NOT          1
  14#define OP_OR           2
  15#define OP_AND          3
  16#define OP_STR_EMPTY    4
  17#define OP_STR_NEMPTY   5
  18#define OP_STR_EQ       6
  19#define OP_STR_NEQ      7
  20#define OP_STR_LT       8
  21#define OP_STR_GT       9
  22#define OP_INT_EQ       10
  23#define OP_INT_NEQ      11
  24#define OP_INT_LT       12
  25#define OP_INT_LE       13
  26#define OP_INT_GT       14
  27#define OP_INT_GE       15
  28#define OP_FILE_EXISTS  16
  29
  30const struct {
  31        int arg;
  32        const char *str;
  33        int op;
  34        int adv;
  35} op_adv[] = {
  36        {1, "=", OP_STR_EQ, 3},
  37        {1, "!=", OP_STR_NEQ, 3},
  38        {1, "<", OP_STR_LT, 3},
  39        {1, ">", OP_STR_GT, 3},
  40        {1, "-eq", OP_INT_EQ, 3},
  41        {1, "-ne", OP_INT_NEQ, 3},
  42        {1, "-lt", OP_INT_LT, 3},
  43        {1, "-le", OP_INT_LE, 3},
  44        {1, "-gt", OP_INT_GT, 3},
  45        {1, "-ge", OP_INT_GE, 3},
  46        {0, "!", OP_NOT, 1},
  47        {0, "-o", OP_OR, 1},
  48        {0, "-a", OP_AND, 1},
  49        {0, "-z", OP_STR_EMPTY, 2},
  50        {0, "-n", OP_STR_NEMPTY, 2},
  51        {0, "-e", OP_FILE_EXISTS, 4},
  52};
  53
  54static int do_test(struct cmd_tbl *cmdtp, int flag, int argc,
  55                   char *const argv[])
  56{
  57        char * const *ap;
  58        int i, op, left, adv, expr, last_expr, last_unop, last_binop;
  59
  60        /* args? */
  61        if (argc < 3)
  62                return 1;
  63
  64#ifdef DEBUG
  65        {
  66                debug("test(%d):", argc);
  67                left = 1;
  68                while (argv[left])
  69                        debug(" '%s'", argv[left++]);
  70        }
  71#endif
  72
  73        left = argc - 1;
  74        ap = argv + 1;
  75        expr = 0;
  76        last_unop = OP_INVALID;
  77        last_binop = OP_INVALID;
  78        last_expr = -1;
  79        while (left > 0) {
  80                for (i = 0; i < ARRAY_SIZE(op_adv); i++) {
  81                        if (left <= op_adv[i].arg)
  82                                continue;
  83                        if (!strcmp(ap[op_adv[i].arg], op_adv[i].str)) {
  84                                op = op_adv[i].op;
  85                                adv = op_adv[i].adv;
  86                                break;
  87                        }
  88                }
  89                if (i == ARRAY_SIZE(op_adv)) {
  90                        expr = 1;
  91                        break;
  92                }
  93                if (left < adv) {
  94                        expr = 1;
  95                        break;
  96                }
  97
  98                switch (op) {
  99                case OP_STR_EMPTY:
 100                        expr = strlen(ap[1]) == 0 ? 1 : 0;
 101                        break;
 102                case OP_STR_NEMPTY:
 103                        expr = strlen(ap[1]) == 0 ? 0 : 1;
 104                        break;
 105                case OP_STR_EQ:
 106                        expr = strcmp(ap[0], ap[2]) == 0;
 107                        break;
 108                case OP_STR_NEQ:
 109                        expr = strcmp(ap[0], ap[2]) != 0;
 110                        break;
 111                case OP_STR_LT:
 112                        expr = strcmp(ap[0], ap[2]) < 0;
 113                        break;
 114                case OP_STR_GT:
 115                        expr = strcmp(ap[0], ap[2]) > 0;
 116                        break;
 117                case OP_INT_EQ:
 118                        expr = simple_strtol(ap[0], NULL, 0) ==
 119                                        simple_strtol(ap[2], NULL, 0);
 120                        break;
 121                case OP_INT_NEQ:
 122                        expr = simple_strtol(ap[0], NULL, 0) !=
 123                                        simple_strtol(ap[2], NULL, 0);
 124                        break;
 125                case OP_INT_LT:
 126                        expr = simple_strtol(ap[0], NULL, 0) <
 127                                        simple_strtol(ap[2], NULL, 0);
 128                        break;
 129                case OP_INT_LE:
 130                        expr = simple_strtol(ap[0], NULL, 0) <=
 131                                        simple_strtol(ap[2], NULL, 0);
 132                        break;
 133                case OP_INT_GT:
 134                        expr = simple_strtol(ap[0], NULL, 0) >
 135                                        simple_strtol(ap[2], NULL, 0);
 136                        break;
 137                case OP_INT_GE:
 138                        expr = simple_strtol(ap[0], NULL, 0) >=
 139                                        simple_strtol(ap[2], NULL, 0);
 140                        break;
 141                case OP_FILE_EXISTS:
 142                        expr = file_exists(ap[1], ap[2], ap[3], FS_TYPE_ANY);
 143                        break;
 144                }
 145
 146                switch (op) {
 147                case OP_OR:
 148                        last_expr = expr;
 149                        last_binop = OP_OR;
 150                        break;
 151                case OP_AND:
 152                        last_expr = expr;
 153                        last_binop = OP_AND;
 154                        break;
 155                case OP_NOT:
 156                        if (last_unop == OP_NOT)
 157                                last_unop = OP_INVALID;
 158                        else
 159                                last_unop = OP_NOT;
 160                        break;
 161                default:
 162                        if (last_unop == OP_NOT) {
 163                                expr = !expr;
 164                                last_unop = OP_INVALID;
 165                        }
 166
 167                        if (last_binop == OP_OR)
 168                                expr = last_expr || expr;
 169                        else if (last_binop == OP_AND)
 170                                expr = last_expr && expr;
 171                        last_binop = OP_INVALID;
 172
 173                        break;
 174                }
 175
 176                ap += adv; left -= adv;
 177        }
 178
 179        expr = !expr;
 180
 181        debug (": returns %d\n", expr);
 182
 183        return expr;
 184}
 185
 186#undef true
 187#undef false
 188
 189U_BOOT_CMD(
 190        test,   CONFIG_SYS_MAXARGS,     1,      do_test,
 191        "minimal test like /bin/sh",
 192        "[args..]"
 193);
 194
 195static int do_false(struct cmd_tbl *cmdtp, int flag, int argc,
 196                    char *const argv[])
 197{
 198        return 1;
 199}
 200
 201U_BOOT_CMD(
 202        false,  CONFIG_SYS_MAXARGS,     1,      do_false,
 203        "do nothing, unsuccessfully",
 204        NULL
 205);
 206
 207static int do_true(struct cmd_tbl *cmdtp, int flag, int argc,
 208                   char *const argv[])
 209{
 210        return 0;
 211}
 212
 213U_BOOT_CMD(
 214        true,   CONFIG_SYS_MAXARGS,     1,      do_true,
 215        "do nothing, successfully",
 216        NULL
 217);
 218