summaryrefslogtreecommitdiffstats
path: root/commands/test.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2007-07-05 18:02:18 +0200
committerSascha Hauer <sha@octopus.labnet.pengutronix.de>2007-07-05 18:02:18 +0200
commit89f0c5c94f919445e1398016be0fc97f7bada3b1 (patch)
treea30ab33a276eb73670de464b2a2103b5aacb5b2b /commands/test.c
parente24bb529b18eccbe5d1082d6eed0eb7353b756e3 (diff)
downloadbarebox-89f0c5c94f919445e1398016be0fc97f7bada3b1.tar.gz
barebox-89f0c5c94f919445e1398016be0fc97f7bada3b1.tar.xz
svn_rev_701
move do_test to own file and reimplement
Diffstat (limited to 'commands/test.c')
-rw-r--r--commands/test.c179
1 files changed, 179 insertions, 0 deletions
diff --git a/commands/test.c b/commands/test.c
new file mode 100644
index 0000000000..8fc2e4a86c
--- /dev/null
+++ b/commands/test.c
@@ -0,0 +1,179 @@
+#include <common.h>
+#include <command.h>
+
+typedef enum {
+ OPT_EQUAL,
+ OPT_NOT_EQUAL,
+ OPT_ARITH_EQUAL,
+ OPT_ARITH_NOT_EQUAL,
+ OPT_ARITH_GREATER_EQUAL,
+ OPT_ARITH_GREATER_THAN,
+ OPT_ARITH_LESS_EQUAL,
+ OPT_ARITH_LESS_THAN,
+ OPT_OR,
+ OPT_AND,
+ OPT_ZERO,
+ OPT_NONZERO,
+ OPT_MAX,
+} test_opts;
+
+static char *test_options[] = {
+ [OPT_EQUAL] = "=",
+ [OPT_NOT_EQUAL] = "!=",
+ [OPT_ARITH_EQUAL] = "-eq",
+ [OPT_ARITH_NOT_EQUAL] = "-ne",
+ [OPT_ARITH_GREATER_EQUAL] = "-ge",
+ [OPT_ARITH_GREATER_THAN] = "-gt",
+ [OPT_ARITH_LESS_EQUAL] = "-le",
+ [OPT_ARITH_LESS_THAN] = "-lt",
+ [OPT_OR] = "-o",
+ [OPT_AND] = "-a",
+ [OPT_ZERO] = "-z",
+ [OPT_NONZERO] = "-n",
+};
+
+static int parse_opt(const char *opt)
+{
+ char **opts = test_options;
+ int i;
+
+ for (i = 0; i < OPT_MAX; i++) {
+ if (!strcmp(opts[i], opt))
+ return i;
+ }
+ return -1;
+}
+
+int
+do_test (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ char **ap;
+ int left, adv, expr, last_expr, neg, last_cmp, opt, zero;
+ ulong a, b;
+
+ if (*argv[0] == '[') {
+ if (*argv[argc - 1] != ']') {
+ printf("[: missing `]'\n");
+ return 1;
+ }
+ argc--;
+ }
+
+ /* args? */
+ if (argc < 2)
+ return 1;
+
+ last_expr = 0;
+ left = argc - 1;
+ ap = argv + 1;
+
+ if (strcmp(ap[0], "!") == 0) {
+ neg = 1;
+ ap++;
+ left--;
+ } else
+ neg = 0;
+
+ expr = -1;
+ last_cmp = -1;
+ last_expr = -1;
+ adv = 0;
+ while (left - adv > 0) {
+ ap += adv; left -= adv;
+
+ adv = 1;
+ opt = parse_opt(ap[0]);
+ switch (opt) {
+ /* one argument options */
+ case OPT_OR:
+ last_expr = expr;
+ last_cmp = 0;
+ continue;
+ case OPT_AND:
+ last_expr = expr;
+ last_cmp = 1;
+ continue;
+
+ /* two argument options */
+ case OPT_ZERO:
+ case OPT_NONZERO:
+ adv = 2;
+ zero = 1;
+ if (ap[1] && *ap[1] != ']' && strlen(ap[1]))
+ zero = 0;
+
+ expr = (opt == OPT_ZERO) ? zero : !zero;
+ break;
+
+ /* three argument options */
+ default:
+ adv = 3;
+ if (left < 3) {
+ expr = 1;
+ break;
+ }
+
+ a = simple_strtol(ap[0], NULL, 0);
+ b = simple_strtol(ap[2], NULL, 0);
+ switch (parse_opt(ap[1])) {
+ case OPT_EQUAL:
+ expr = strcmp(ap[0], ap[2]) == 0;
+ break;
+ case OPT_NOT_EQUAL:
+ expr = strcmp(ap[0], ap[2]) != 0;
+ break;
+ case OPT_ARITH_EQUAL:
+ printf("equal: %d %d\n", a, b);
+ expr = a == b;
+ break;
+ case OPT_ARITH_NOT_EQUAL:
+ expr = a != b;
+ break;
+ case OPT_ARITH_LESS_THAN:
+ expr = a < b;
+ break;
+ case OPT_ARITH_LESS_EQUAL:
+ expr = a <= b;
+ break;
+ case OPT_ARITH_GREATER_THAN:
+ expr = a > b;
+ break;
+ case OPT_ARITH_GREATER_EQUAL:
+ expr = a >= b;
+ break;
+ default:
+ expr = 1;
+ goto out;
+ }
+ }
+
+ if (last_cmp == 0)
+ expr = last_expr || expr;
+ else if (last_cmp == 1)
+ expr = last_expr && expr;
+ last_cmp = -1;
+ }
+out:
+ if (neg)
+ expr = !expr;
+
+ expr = !expr;
+
+
+ return expr;
+}
+
+char *test_aliases[] = { "[", NULL};
+
+static __maybe_unused char cmd_test_help[] =
+"Usage: test [OPTIONS]\n"
+"options: !, =, !=, -eq, -ne, -ge, -gt, -le, -lt, -o, -a, -z, -n\n"
+"see 'man test' on your PC for more information.\n";
+
+U_BOOT_CMD_START(test)
+ .aliases = test_aliases,
+ .maxargs = CONFIG_MAXARGS,
+ .cmd = do_test,
+ .usage = "minimal test like /bin/sh",
+ U_BOOT_CMD_HELP(cmd_test_help)
+U_BOOT_CMD_END