Merge branch 'master' of git://git.denx.de/u-boot-coldfire
[platform/kernel/u-boot.git] / 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 #include <common.h>
9 #include <command.h>
10 #include <fs.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(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
55 {
56         char * const *ap;
57         int i, op, left, adv, expr, last_expr, last_unop, last_binop;
58
59         /* args? */
60         if (argc < 3)
61                 return 1;
62
63 #ifdef DEBUG
64         {
65                 debug("test(%d):", argc);
66                 left = 1;
67                 while (argv[left])
68                         debug(" '%s'", argv[left++]);
69         }
70 #endif
71
72         left = argc - 1;
73         ap = argv + 1;
74         expr = 0;
75         last_unop = OP_INVALID;
76         last_binop = OP_INVALID;
77         last_expr = -1;
78         while (left > 0) {
79                 for (i = 0; i < ARRAY_SIZE(op_adv); i++) {
80                         if (left <= op_adv[i].arg)
81                                 continue;
82                         if (!strcmp(ap[op_adv[i].arg], op_adv[i].str)) {
83                                 op = op_adv[i].op;
84                                 adv = op_adv[i].adv;
85                                 break;
86                         }
87                 }
88                 if (i == ARRAY_SIZE(op_adv)) {
89                         expr = 1;
90                         break;
91                 }
92                 if (left < adv) {
93                         expr = 1;
94                         break;
95                 }
96
97                 switch (op) {
98                 case OP_STR_EMPTY:
99                         expr = strlen(ap[1]) == 0 ? 1 : 0;
100                         break;
101                 case OP_STR_NEMPTY:
102                         expr = strlen(ap[1]) == 0 ? 0 : 1;
103                         break;
104                 case OP_STR_EQ:
105                         expr = strcmp(ap[0], ap[2]) == 0;
106                         break;
107                 case OP_STR_NEQ:
108                         expr = strcmp(ap[0], ap[2]) != 0;
109                         break;
110                 case OP_STR_LT:
111                         expr = strcmp(ap[0], ap[2]) < 0;
112                         break;
113                 case OP_STR_GT:
114                         expr = strcmp(ap[0], ap[2]) > 0;
115                         break;
116                 case OP_INT_EQ:
117                         expr = simple_strtol(ap[0], NULL, 10) ==
118                                         simple_strtol(ap[2], NULL, 10);
119                         break;
120                 case OP_INT_NEQ:
121                         expr = simple_strtol(ap[0], NULL, 10) !=
122                                         simple_strtol(ap[2], NULL, 10);
123                         break;
124                 case OP_INT_LT:
125                         expr = simple_strtol(ap[0], NULL, 10) <
126                                         simple_strtol(ap[2], NULL, 10);
127                         break;
128                 case OP_INT_LE:
129                         expr = simple_strtol(ap[0], NULL, 10) <=
130                                         simple_strtol(ap[2], NULL, 10);
131                         break;
132                 case OP_INT_GT:
133                         expr = simple_strtol(ap[0], NULL, 10) >
134                                         simple_strtol(ap[2], NULL, 10);
135                         break;
136                 case OP_INT_GE:
137                         expr = simple_strtol(ap[0], NULL, 10) >=
138                                         simple_strtol(ap[2], NULL, 10);
139                         break;
140                 case OP_FILE_EXISTS:
141                         expr = file_exists(ap[1], ap[2], ap[3], FS_TYPE_ANY);
142                         break;
143                 }
144
145                 switch (op) {
146                 case OP_OR:
147                         last_expr = expr;
148                         last_binop = OP_OR;
149                         break;
150                 case OP_AND:
151                         last_expr = expr;
152                         last_binop = OP_AND;
153                         break;
154                 case OP_NOT:
155                         if (last_unop == OP_NOT)
156                                 last_unop = OP_INVALID;
157                         else
158                                 last_unop = OP_NOT;
159                         break;
160                 default:
161                         if (last_unop == OP_NOT) {
162                                 expr = !expr;
163                                 last_unop = OP_INVALID;
164                         }
165
166                         if (last_binop == OP_OR)
167                                 expr = last_expr || expr;
168                         else if (last_binop == OP_AND)
169                                 expr = last_expr && expr;
170                         last_binop = OP_INVALID;
171
172                         break;
173                 }
174
175                 ap += adv; left -= adv;
176         }
177
178         expr = !expr;
179
180         debug (": returns %d\n", expr);
181
182         return expr;
183 }
184
185 #undef true
186 #undef false
187
188 U_BOOT_CMD(
189         test,   CONFIG_SYS_MAXARGS,     1,      do_test,
190         "minimal test like /bin/sh",
191         "[args..]"
192 );
193
194 static int do_false(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
195 {
196         return 1;
197 }
198
199 U_BOOT_CMD(
200         false,  CONFIG_SYS_MAXARGS,     1,      do_false,
201         "do nothing, unsuccessfully",
202         NULL
203 );
204
205 static int do_true(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
206 {
207         return 0;
208 }
209
210 U_BOOT_CMD(
211         true,   CONFIG_SYS_MAXARGS,     1,      do_true,
212         "do nothing, successfully",
213         NULL
214 );