Commit 47ab5ad14575531798431f0d1e8f83ee9bb0a87e
Committed by
Wolfgang Denk
1 parent
652e53546b
Exists in
master
and in
54 other branches
cmd_setexpr: allow memory addresses in expressions
This patch add functionality to use memory addresses in expressions. This increases the power of expressions substantially It adheres to the standard convemtions: memory addresses can be given in the format *address (e.g. *1000) Rationale for this change is that it allows masking off bits from a byte that is obtained by reading data from e.g. i2c. Signed-off-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com> Fix warning: control reaches end of non-void function Signed-off-by: Wolfgang Denk <wd@denx.de>
Showing 1 changed file with 30 additions and 4 deletions Side-by-side Diff
common/cmd_setexpr.c
... | ... | @@ -28,10 +28,33 @@ |
28 | 28 | #include <config.h> |
29 | 29 | #include <command.h> |
30 | 30 | |
31 | +static ulong get_arg(char *s, int w) | |
32 | +{ | |
33 | + ulong *p; | |
34 | + | |
35 | + /* | |
36 | + * if the parameter starts with a '*' then assume | |
37 | + * it is a pointer to the value we want | |
38 | + */ | |
39 | + | |
40 | + if (s[0] == '*') { | |
41 | + p = (ulong *)simple_strtoul(&s[1], NULL, 16); | |
42 | + switch (w) { | |
43 | + case 1: return((ulong)(*(uchar *)p)); | |
44 | + case 2: return((ulong)(*(ushort *)p)); | |
45 | + case 4: | |
46 | + default: return(*p); | |
47 | + } | |
48 | + } else { | |
49 | + return simple_strtoul(s, NULL, 16); | |
50 | + } | |
51 | +} | |
52 | + | |
31 | 53 | int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
32 | 54 | { |
33 | 55 | ulong a, b; |
34 | 56 | char buf[16]; |
57 | + int w; | |
35 | 58 | |
36 | 59 | /* Validate arguments */ |
37 | 60 | if ((argc != 5) || (strlen(argv[3]) != 1)) { |
38 | 61 | |
... | ... | @@ -39,9 +62,11 @@ |
39 | 62 | return 1; |
40 | 63 | } |
41 | 64 | |
42 | - a = simple_strtoul(argv[2], NULL, 16); | |
43 | - b = simple_strtoul(argv[4], NULL, 16); | |
65 | + w = cmd_get_data_size(argv[0], 4); | |
44 | 66 | |
67 | + a = get_arg(argv[2], w); | |
68 | + b = get_arg(argv[4], w); | |
69 | + | |
45 | 70 | switch (argv[3][0]) { |
46 | 71 | case '|': sprintf(buf, "%lx", (a | b)); break; |
47 | 72 | case '&': sprintf(buf, "%lx", (a & b)); break; |
48 | 73 | |
... | ... | @@ -64,8 +89,9 @@ |
64 | 89 | U_BOOT_CMD( |
65 | 90 | setexpr, 5, 0, do_setexpr, |
66 | 91 | "set environment variable as the result of eval expression", |
67 | - "name value1 <op> value2\n" | |
92 | + "[.b, .w, .l] name value1 <op> value2\n" | |
68 | 93 | " - set environment variable 'name' to the result of the evaluated\n" |
69 | - " express specified by <op>. <op> can be &, |, ^, +, -, *, /, %" | |
94 | + " express specified by <op>. <op> can be &, |, ^, +, -, *, /, %\n" | |
95 | + " size argument is only meaningful if value1 and/or value2 are memory addresses" | |
70 | 96 | ); |
-
mentioned in commit 25a43a