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