Blame view
common/cmd_itest.c
4.17 KB
2d1a537d8
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* * (C) Copyright 2003 * Tait Electronics Limited, Christchurch, New Zealand * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of |
cd0a9de68
|
15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2d1a537d8
|
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
* GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ /* * This file provides a shell like 'test' function to return * true/false from an integer or string compare of two memory * locations or a location and a scalar/literal. * A few parts were lifted from bash 'test' command */ #include <common.h> #include <config.h> #include <command.h> #define EQ 0 #define NE 1 #define LT 2 #define GT 3 #define LE 4 #define GE 5 struct op_tbl_s { char *op; /* operator string */ int opcode; /* internal representation of opcode */ }; typedef struct op_tbl_s op_tbl_t; |
fc9903f38
|
48 |
static const op_tbl_t op_table [] = { |
2d1a537d8
|
49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
{ "-lt", LT }, { "<" , LT }, { "-gt", GT }, { ">" , GT }, { "-eq", EQ }, { "==" , EQ }, { "-ne", NE }, { "!=" , NE }, { "<>" , NE }, { "-ge", GE }, { ">=" , GE }, { "-le", LE }, { "<=" , LE }, }; |
2d1a537d8
|
63 64 |
static long evalexp(char *s, int w) { |
f3651764e
|
65 66 |
long l = 0; long *p; |
2d1a537d8
|
67 68 69 70 |
/* if the parameter starts with a * then assume is a pointer to the value we want */ if (s[0] == '*') { p = (long *)simple_strtoul(&s[1], NULL, 16); |
f3651764e
|
71 72 73 74 75 |
switch (w) { case 1: return((long)(*(unsigned char *)p)); case 2: return((long)(*(unsigned short *)p)); case 4: return(*p); } |
2d1a537d8
|
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
} else { l = simple_strtoul(s, NULL, 16); } return (l & ((1 << (w * 8)) - 1)); } static char * evalstr(char *s) { /* if the parameter starts with a * then assume a string pointer else its a literal */ if (s[0] == '*') { return (char *)simple_strtoul(&s[1], NULL, 16); } else { return s; } } static int stringcomp(char *s, char *t, int op) { |
cc22b795f
|
95 |
int p; |
2d1a537d8
|
96 97 98 99 |
char *l, *r; l = evalstr(s); r = evalstr(t); |
cc22b795f
|
100 |
p = strcmp(l, r); |
2d1a537d8
|
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
switch (op) { case EQ: return (p == 0); case NE: return (p != 0); case LT: return (p < 0); case GT: return (p > 0); case LE: return (p <= 0); case GE: return (p >= 0); } return (0); } static int arithcomp (char *s, char *t, int op, int w) { long l, r; l = evalexp (s, w); r = evalexp (t, w); switch (op) { case EQ: return (l == r); case NE: return (l != r); case LT: return (l < r); case GT: return (l > r); case LE: return (l <= r); case GE: return (l >= r); } return (0); } |
088f1b199
|
129 |
static int binary_test(char *op, char *arg1, char *arg2, int w) |
2d1a537d8
|
130 131 |
{ int len, i; |
fc9903f38
|
132 |
const op_tbl_t *optp; |
2d1a537d8
|
133 134 135 136 |
len = strlen(op); for (optp = (op_tbl_t *)&op_table, i = 0; |
fc9903f38
|
137 |
i < ARRAY_SIZE(op_table); |
2d1a537d8
|
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
optp++, i++) { if ((strncmp (op, optp->op, len) == 0) && (len == strlen (optp->op))) { if (w == 0) { return (stringcomp(arg1, arg2, optp->opcode)); } else { return (arithcomp (arg1, arg2, optp->opcode, w)); } } } printf("Unknown operator '%s' ", op); return 0; /* op code not found */ } /* command line interface to the shell test */ |
088f1b199
|
155 |
static int do_itest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
2d1a537d8
|
156 |
{ |
cd0a9de68
|
157 |
int value, w; |
2d1a537d8
|
158 |
|
cd0a9de68
|
159 |
/* Validate arguments */ |
47e26b1bf
|
160 |
if ((argc != 4)) |
4c12eeb8b
|
161 |
return CMD_RET_USAGE; |
2d1a537d8
|
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
/* Check for a data width specification. * Defaults to long (4) if no specification. * Uses -2 as 'width' for .s (string) so as not to upset existing code */ switch (w = cmd_get_data_size(argv[0], 4)) { case 1: case 2: case 4: value = binary_test (argv[2], argv[1], argv[3], w); break; case -2: value = binary_test (argv[2], argv[1], argv[3], 0); break; case -1: default: puts("Invalid data width specifier "); value = 0; break; } return !value; } U_BOOT_CMD( itest, 4, 0, do_itest, |
2fb2604d5
|
189 |
"return true/false on integer compare", |
a89c33db9
|
190 |
"[.b, .w, .l, .s] [*]value1 <op> [*]value2" |
2d1a537d8
|
191 |
); |