Merge tag 'efi-2020-07-rc6' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
[oweals/u-boot.git] / cmd / test.c
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
30 const 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
54 static 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
189 U_BOOT_CMD(
190         test,   CONFIG_SYS_MAXARGS,     1,      do_test,
191         "minimal test like /bin/sh",
192         "[args..]"
193 );
194
195 static int do_false(struct cmd_tbl *cmdtp, int flag, int argc,
196                     char *const argv[])
197 {
198         return 1;
199 }
200
201 U_BOOT_CMD(
202         false,  CONFIG_SYS_MAXARGS,     1,      do_false,
203         "do nothing, unsuccessfully",
204         NULL
205 );
206
207 static int do_true(struct cmd_tbl *cmdtp, int flag, int argc,
208                    char *const argv[])
209 {
210         return 0;
211 }
212
213 U_BOOT_CMD(
214         true,   CONFIG_SYS_MAXARGS,     1,      do_true,
215         "do nothing, successfully",
216         NULL
217 );