[U-Boot] [PATCH 7/7] cmd_setexpr: allow memory addresses and env vars in expressions

This patch add functionality to use memory addresses and environment variables 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), environment variables as $this_var. environment variables are not processed recursively but can contain both constants and memory addresses.
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
---
If recursive environment vars is desired: this can be added easily by changing the if statement into a while statement. I figured that would be somewhat over the top though (and, unless you take special precautions you can run into an endless loop if an env var contains its own name. If it is desired, please let me know and I happily will add it.
And a snippet from the test log: => mm.b 1000 00001000: de ? 12 00001001: ad ? 34 00001002: be ? 56 00001003: ef ? 78 00001004: de ? 00001005: ad ? . => setexpr aap 3 + *1000 => echo $aap 1234567b => setexpr.b aap 3 + *1000 => echo $aap 15 => setexpr.w nut $aap + *1000 => echo $nut 1249 --- common/cmd_setexpr.c | 33 +++++++++++++++++++++++++++++---- 1 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/common/cmd_setexpr.c b/common/cmd_setexpr.c index f8b5d4d..6ea9296 100644 --- a/common/cmd_setexpr.c +++ b/common/cmd_setexpr.c @@ -28,10 +28,32 @@ #include <config.h> #include <command.h>
+static ulong get_arg(char *s, int w) +{ + ulong *p; + + /* if the parameter starts with a $ replace it with the environment value */ + if (s[0] == '$') { + s = getenv(&s[1]); + } + /* if the parameter starts with a * then assume is a pointer to the value we want */ + if (s[0] == '*') { + p = (ulong *)simple_strtoul(&s[1], NULL, 16); + switch (w) { + case 1: return((ulong)(*(uchar *)p)); + case 2: return((ulong)(*(ushort *)p)); + case 4: return(*p); + } + } else { + return simple_strtoul(s, NULL, 16); + } +} + int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong a, b; char buf[16]; + int w;
/* Validate arguments */ if ((argc != 5) || (strlen(argv[3]) != 1)) { @@ -39,8 +61,10 @@ int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; }
- a = simple_strtoul(argv[2], NULL, 16); - b = simple_strtoul(argv[4], NULL, 16); + w = cmd_get_data_size(argv[0], 4); + + a = get_arg(argv[2], w); + b = get_arg(argv[4], w);
switch (argv[3][0]) { case '|': sprintf(buf, "%lx", (a | b)); break; @@ -64,7 +88,8 @@ int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD( setexpr, 5, 0, do_setexpr, "set environment variable as the result of eval expression", - "name value1 <op> value2\n" + "[.b, .w, .l] name value1 <op> value2\n" " - set environment variable 'name' to the result of the evaluated\n" - " express specified by <op>. <op> can be &, |, ^, +, -, *, /, %" + " express specified by <op>. <op> can be &, |, ^, +, -, *, /, %\n" + " size argument is only meaningful if value1 and/or value2 are memory addresses" );

Resubmitted the patch (see previous message) as I noticed a \n in the help was missing. Apologies for any inconvenience.

Hi Frans,
Resubmitted the patch (see previous message) as I noticed a \n in the help was missing. Apologies for any inconvenience.
Then you actually submitted a Version 2 of the patch and should have expressed that with a "--subject-prefix="PATCH v2" argument to git format-patch.
Cheers Detlev

Hi Frans,
This patch add functionality to use memory addresses and environment variables 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), environment variables as $this_var.
This has the same ${var} problem as your other patch.
Cheers Detlev

2010/2/26 Detlev Zundel dzu@denx.de:
Hi Frans,
This patch add functionality to use memory addresses and environment variables 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), environment variables as $this_var.
This has the same ${var} problem as your other patch.
I'll take it out and resubmit, this time amending the subject line. I haven't really mastered all git options yet and am not fully up to speed on how to submit patches. Apologies for any inconvenience.
Frans
participants (2)
-
Detlev Zundel
-
Frans Meulenbroeks