blob: 4774d296487496b437c3898b550fc513a9b621e4 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Peter Tysereabe6d92009-10-16 17:36:25 -05002/*
3 * Copyright 2000-2009
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
Peter Tysereabe6d92009-10-16 17:36:25 -05005 */
6
Peter Tysereabe6d92009-10-16 17:36:25 -05007#include <command.h>
Stephen Warren0700db62014-02-03 13:21:06 -07008#include <fs.h>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Tom Rinidec7ea02024-05-20 13:35:03 -060010#include <vsprintf.h>
Tom Riniee8ed542025-05-14 16:46:00 -060011#include <linux/string.h>
Peter Tysereabe6d92009-10-16 17:36:25 -050012
Stephen Warren28cca552014-02-03 13:21:02 -070013#define OP_INVALID 0
Stephen Warren08b763b2014-02-03 13:21:04 -070014#define OP_NOT 1
Stephen Warren28cca552014-02-03 13:21:02 -070015#define OP_OR 2
16#define OP_AND 3
17#define OP_STR_EMPTY 4
18#define OP_STR_NEMPTY 5
19#define OP_STR_EQ 6
20#define OP_STR_NEQ 7
21#define OP_STR_LT 8
22#define OP_STR_GT 9
23#define OP_INT_EQ 10
24#define OP_INT_NEQ 11
25#define OP_INT_LT 12
26#define OP_INT_LE 13
27#define OP_INT_GT 14
28#define OP_INT_GE 15
Stephen Warren0700db62014-02-03 13:21:06 -070029#define OP_FILE_EXISTS 16
Stephen Warren28cca552014-02-03 13:21:02 -070030
31const struct {
32 int arg;
33 const char *str;
34 int op;
35 int adv;
36} op_adv[] = {
Stephen Warren28cca552014-02-03 13:21:02 -070037 {1, "=", OP_STR_EQ, 3},
38 {1, "!=", OP_STR_NEQ, 3},
39 {1, "<", OP_STR_LT, 3},
40 {1, ">", OP_STR_GT, 3},
41 {1, "-eq", OP_INT_EQ, 3},
42 {1, "-ne", OP_INT_NEQ, 3},
43 {1, "-lt", OP_INT_LT, 3},
44 {1, "-le", OP_INT_LE, 3},
45 {1, "-gt", OP_INT_GT, 3},
46 {1, "-ge", OP_INT_GE, 3},
Stephen Warren08b763b2014-02-03 13:21:04 -070047 {0, "!", OP_NOT, 1},
Stephen Warren4c1b2812014-02-03 13:21:03 -070048 {0, "-o", OP_OR, 1},
49 {0, "-a", OP_AND, 1},
50 {0, "-z", OP_STR_EMPTY, 2},
51 {0, "-n", OP_STR_NEMPTY, 2},
Stephen Warren0700db62014-02-03 13:21:06 -070052 {0, "-e", OP_FILE_EXISTS, 4},
Stephen Warren28cca552014-02-03 13:21:02 -070053};
54
Simon Glassed38aef2020-05-10 11:40:03 -060055static int do_test(struct cmd_tbl *cmdtp, int flag, int argc,
56 char *const argv[])
Peter Tysereabe6d92009-10-16 17:36:25 -050057{
Wolfgang Denk6262d0212010-06-28 22:00:46 +020058 char * const *ap;
Stephen Warren08b763b2014-02-03 13:21:04 -070059 int i, op, left, adv, expr, last_expr, last_unop, last_binop;
Peter Tysereabe6d92009-10-16 17:36:25 -050060
61 /* args? */
62 if (argc < 3)
63 return 1;
64
Joe Hershbergereeff2282012-08-17 10:56:12 +000065#ifdef DEBUG
Peter Tysereabe6d92009-10-16 17:36:25 -050066 {
Joe Hershbergereeff2282012-08-17 10:56:12 +000067 debug("test(%d):", argc);
Peter Tysereabe6d92009-10-16 17:36:25 -050068 left = 1;
69 while (argv[left])
Joe Hershbergereeff2282012-08-17 10:56:12 +000070 debug(" '%s'", argv[left++]);
Peter Tysereabe6d92009-10-16 17:36:25 -050071 }
72#endif
73
Stephen Warren08b763b2014-02-03 13:21:04 -070074 left = argc - 1;
75 ap = argv + 1;
Stephen Warren4f6e1aa2014-02-03 13:21:05 -070076 expr = 0;
Stephen Warren08b763b2014-02-03 13:21:04 -070077 last_unop = OP_INVALID;
78 last_binop = OP_INVALID;
Peter Tysereabe6d92009-10-16 17:36:25 -050079 last_expr = -1;
80 while (left > 0) {
Stephen Warren28cca552014-02-03 13:21:02 -070081 for (i = 0; i < ARRAY_SIZE(op_adv); i++) {
82 if (left <= op_adv[i].arg)
83 continue;
84 if (!strcmp(ap[op_adv[i].arg], op_adv[i].str)) {
85 op = op_adv[i].op;
86 adv = op_adv[i].adv;
87 break;
88 }
89 }
90 if (i == ARRAY_SIZE(op_adv)) {
Peter Tysereabe6d92009-10-16 17:36:25 -050091 expr = 1;
92 break;
93 }
Stephen Warren28cca552014-02-03 13:21:02 -070094 if (left < adv) {
95 expr = 1;
96 break;
Peter Tysereabe6d92009-10-16 17:36:25 -050097 }
98
Stephen Warren28cca552014-02-03 13:21:02 -070099 switch (op) {
100 case OP_STR_EMPTY:
101 expr = strlen(ap[1]) == 0 ? 1 : 0;
102 break;
103 case OP_STR_NEMPTY:
104 expr = strlen(ap[1]) == 0 ? 0 : 1;
105 break;
106 case OP_STR_EQ:
107 expr = strcmp(ap[0], ap[2]) == 0;
108 break;
109 case OP_STR_NEQ:
110 expr = strcmp(ap[0], ap[2]) != 0;
111 break;
112 case OP_STR_LT:
113 expr = strcmp(ap[0], ap[2]) < 0;
114 break;
115 case OP_STR_GT:
116 expr = strcmp(ap[0], ap[2]) > 0;
117 break;
118 case OP_INT_EQ:
T Karthik Reddyd3964102019-09-11 15:39:53 +0200119 expr = simple_strtol(ap[0], NULL, 0) ==
120 simple_strtol(ap[2], NULL, 0);
Stephen Warren28cca552014-02-03 13:21:02 -0700121 break;
122 case OP_INT_NEQ:
T Karthik Reddyd3964102019-09-11 15:39:53 +0200123 expr = simple_strtol(ap[0], NULL, 0) !=
124 simple_strtol(ap[2], NULL, 0);
Stephen Warren28cca552014-02-03 13:21:02 -0700125 break;
126 case OP_INT_LT:
T Karthik Reddyd3964102019-09-11 15:39:53 +0200127 expr = simple_strtol(ap[0], NULL, 0) <
128 simple_strtol(ap[2], NULL, 0);
Stephen Warren28cca552014-02-03 13:21:02 -0700129 break;
130 case OP_INT_LE:
T Karthik Reddyd3964102019-09-11 15:39:53 +0200131 expr = simple_strtol(ap[0], NULL, 0) <=
132 simple_strtol(ap[2], NULL, 0);
Stephen Warren28cca552014-02-03 13:21:02 -0700133 break;
134 case OP_INT_GT:
T Karthik Reddyd3964102019-09-11 15:39:53 +0200135 expr = simple_strtol(ap[0], NULL, 0) >
136 simple_strtol(ap[2], NULL, 0);
Stephen Warren28cca552014-02-03 13:21:02 -0700137 break;
138 case OP_INT_GE:
T Karthik Reddyd3964102019-09-11 15:39:53 +0200139 expr = simple_strtol(ap[0], NULL, 0) >=
140 simple_strtol(ap[2], NULL, 0);
Stephen Warren28cca552014-02-03 13:21:02 -0700141 break;
Stephen Warren0700db62014-02-03 13:21:06 -0700142 case OP_FILE_EXISTS:
143 expr = file_exists(ap[1], ap[2], ap[3], FS_TYPE_ANY);
144 break;
Peter Tysereabe6d92009-10-16 17:36:25 -0500145 }
146
Stephen Warren28cca552014-02-03 13:21:02 -0700147 switch (op) {
148 case OP_OR:
149 last_expr = expr;
Stephen Warren08b763b2014-02-03 13:21:04 -0700150 last_binop = OP_OR;
Stephen Warren28cca552014-02-03 13:21:02 -0700151 break;
152 case OP_AND:
153 last_expr = expr;
Stephen Warren08b763b2014-02-03 13:21:04 -0700154 last_binop = OP_AND;
155 break;
156 case OP_NOT:
157 if (last_unop == OP_NOT)
158 last_unop = OP_INVALID;
159 else
160 last_unop = OP_NOT;
Stephen Warren28cca552014-02-03 13:21:02 -0700161 break;
162 default:
Stephen Warren08b763b2014-02-03 13:21:04 -0700163 if (last_unop == OP_NOT) {
164 expr = !expr;
165 last_unop = OP_INVALID;
166 }
167
168 if (last_binop == OP_OR)
Peter Tysereabe6d92009-10-16 17:36:25 -0500169 expr = last_expr || expr;
Stephen Warren08b763b2014-02-03 13:21:04 -0700170 else if (last_binop == OP_AND)
Peter Tysereabe6d92009-10-16 17:36:25 -0500171 expr = last_expr && expr;
Stephen Warren08b763b2014-02-03 13:21:04 -0700172 last_binop = OP_INVALID;
173
Stephen Warren28cca552014-02-03 13:21:02 -0700174 break;
Peter Tysereabe6d92009-10-16 17:36:25 -0500175 }
176
177 ap += adv; left -= adv;
178 }
179
Peter Tysereabe6d92009-10-16 17:36:25 -0500180 expr = !expr;
181
182 debug (": returns %d\n", expr);
183
184 return expr;
185}
186
Heiko Schocher7e5a16c2015-04-27 07:42:05 +0200187#undef true
188#undef false
189
Peter Tysereabe6d92009-10-16 17:36:25 -0500190U_BOOT_CMD(
191 test, CONFIG_SYS_MAXARGS, 1, do_test,
192 "minimal test like /bin/sh",
193 "[args..]"
194);
Peter Tysercc35c492009-10-16 17:36:27 -0500195
Simon Glassed38aef2020-05-10 11:40:03 -0600196static int do_false(struct cmd_tbl *cmdtp, int flag, int argc,
197 char *const argv[])
Peter Tysercc35c492009-10-16 17:36:27 -0500198{
199 return 1;
200}
201
202U_BOOT_CMD(
203 false, CONFIG_SYS_MAXARGS, 1, do_false,
204 "do nothing, unsuccessfully",
205 NULL
206);
207
Simon Glassed38aef2020-05-10 11:40:03 -0600208static int do_true(struct cmd_tbl *cmdtp, int flag, int argc,
209 char *const argv[])
Peter Tysercc35c492009-10-16 17:36:27 -0500210{
211 return 0;
212}
213
214U_BOOT_CMD(
215 true, CONFIG_SYS_MAXARGS, 1, do_true,
216 "do nothing, successfully",
217 NULL
218);