Commit cc22b795fb5fee72bd567eec5d33a11e8b989086

Authored by Wolfgang Denk
1 parent 518075fc6a
Exists in master and in 57 other branches 8qm-imx_v2020.04_5.4.70_2.3.0, emb_lf-6.6.52-2.2.0, emb_lf_v2022.04, emb_lf_v2023.04, emb_lf_v2024.04, imx_v2015.04_4.1.15_1.0.0_ga, pitx_8mp_lf_v2020.04, smarc-8m-android-10.0.0_2.6.0, smarc-8m-android-11.0.0_2.0.0, smarc-8mp-android-11.0.0_2.0.0, smarc-emmc-imx_v2014.04_3.10.53_1.1.0_ga, smarc-emmc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx-l5.0.0_1.0.0-ga, smarc-imx6_v2018.03_4.14.98_2.0.0_ga, smarc-imx7_v2017.03_4.9.11_1.0.0_ga, smarc-imx7_v2018.03_4.14.98_2.0.0_ga, smarc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx_v2015.04_4.1.15_1.0.0_ga, smarc-imx_v2017.03_4.9.11_1.0.0_ga, smarc-imx_v2017.03_4.9.88_2.0.0_ga, smarc-imx_v2017.03_o8.1.0_1.3.0_8m, smarc-imx_v2018.03_4.14.78_1.0.0_ga, smarc-m6.0.1_2.1.0-ga, smarc-n7.1.2_2.0.0-ga, smarc-rel_imx_4.1.15_2.0.0_ga, smarc_8m-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8m-imx_v2019.04_4.19.35_1.1.0, smarc_8m_00d0-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2019.04_4.19.35_1.1.0, smarc_8mm-imx_v2020.04_5.4.24_2.1.0, smarc_8mp_lf_v2020.04, smarc_8mq-imx_v2020.04_5.4.24_2.1.0, smarc_8mq_lf_v2020.04, ti-u-boot-2015.07, u-boot-2013.01.y, v2013.10, v2013.10-smarct33, v2013.10-smartmen, v2014.01, v2014.04, v2014.04-smarct33, v2014.04-smarct33-emmc, v2014.04-smartmen, v2014.07, v2014.07-smarct33, v2014.07-smartmen, v2015.07-smarct33, v2015.07-smarct33-emmc, v2015.07-smarct4x, v2016.05-dlt, v2016.05-smarct3x, v2016.05-smarct3x-emmc, v2016.05-smarct4x, v2017.01-smarct3x, v2017.01-smarct3x-emmc, v2017.01-smarct4x

itest: fix result of string compares

The implementation of the string compare function of the "itest"
command was weird, as only the length of the shortest argument was
included in the compare, with the result that something like
"itest.s abd == abddef" would return TRUE.  Fix this.

Signed-off-by: Wolfgang Denk <wd@denx.de>
Acked-by: Detlev Zundel <dzu@denx.de>

Showing 1 changed file with 2 additions and 5 deletions Inline Diff

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