xref: /openbmc/u-boot/cmd/test.c (revision cf0bcd7d)
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 );
215