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