summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2020-11-01 14:15:43 -0700
committerTom Rini <trini@konsulko.com>2020-12-01 10:33:38 -0500
commitf66bee41abe8288e5fd6aa6b61ff23c5f8a2c851 (patch)
tree5b4baf50efcea1d9666f139b181a5972c7fa23bb
parent8f4aa7ddb908369db971d4c31850ca1eef2e3687 (diff)
downloadu-boot-f66bee41abe8288e5fd6aa6b61ff23c5f8a2c851.tar.gz
setexpr: Convert to use a struct for values
At present a ulong is used to hold operand values. This means that strings cannot be used. While most operations are not useful for strings, concatenation is. As a starting point to supporting strings, convert the code to use a struct instead of a ulong for operands. Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r--cmd/setexpr.c111
1 files changed, 67 insertions, 44 deletions
diff --git a/cmd/setexpr.c b/cmd/setexpr.c
index d364dbc2bc..8a3654505d 100644
--- a/cmd/setexpr.c
+++ b/cmd/setexpr.c
@@ -15,8 +15,19 @@
#include <log.h>
#include <mapmem.h>
-static ulong get_arg(char *s, int w)
+/**
+ * struct expr_arg: Holds an argument to an expression
+ *
+ * @ival: Integer value (if width is not CMD_DATA_SIZE_STR)
+ */
+struct expr_arg {
+ ulong ival;
+};
+
+static int get_arg(char *s, int w, struct expr_arg *argp)
{
+ struct expr_arg arg;
+
/*
* If the parameter starts with a '*' then assume it is a pointer to
* the value we want.
@@ -32,26 +43,33 @@ static ulong get_arg(char *s, int w)
p = map_sysmem(addr, sizeof(uchar));
val = (ulong)*(uchar *)p;
unmap_sysmem(p);
- return val;
+ arg.ival = val;
+ break;
case 2:
p = map_sysmem(addr, sizeof(ushort));
val = (ulong)*(ushort *)p;
unmap_sysmem(p);
- return val;
+ arg.ival = val;
+ break;
case 4:
p = map_sysmem(addr, sizeof(u32));
val = *(u32 *)p;
unmap_sysmem(p);
- return val;
+ arg.ival = val;
+ break;
default:
p = map_sysmem(addr, sizeof(ulong));
val = *p;
unmap_sysmem(p);
- return val;
+ arg.ival = val;
+ break;
}
} else {
- return simple_strtoul(s, NULL, 16);
+ arg.ival = simple_strtoul(s, NULL, 16);
}
+ *argp = arg;
+
+ return 0;
}
#ifdef CONFIG_REGEX
@@ -321,7 +339,7 @@ static int regex_sub_var(const char *name, const char *r, const char *s,
static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
- ulong a, b;
+ struct expr_arg aval, bval;
ulong value;
int w;
@@ -339,13 +357,12 @@ static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
w = cmd_get_data_size(argv[0], 4);
- a = get_arg(argv[2], w);
+ if (get_arg(argv[2], w, &aval))
+ return CMD_RET_FAILURE;
/* plain assignment: "setexpr name value" */
- if (argc == 3) {
- env_set_hex(argv[1], a);
- return 0;
- }
+ if (argc == 3)
+ return env_set_hex(argv[1], aval.ival);
/* 5 or 6 args (6 args only with [g]sub) */
#ifdef CONFIG_REGEX
@@ -367,39 +384,45 @@ static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
if (strlen(argv[3]) != 1)
return CMD_RET_USAGE;
- b = get_arg(argv[4], w);
-
- switch (argv[3][0]) {
- case '|':
- value = a | b;
- break;
- case '&':
- value = a & b;
- break;
- case '+':
- value = a + b;
- break;
- case '^':
- value = a ^ b;
- break;
- case '-':
- value = a - b;
- break;
- case '*':
- value = a * b;
- break;
- case '/':
- value = a / b;
- break;
- case '%':
- value = a % b;
- break;
- default:
- printf("invalid op\n");
- return 1;
- }
+ if (get_arg(argv[4], w, &bval))
+ return CMD_RET_FAILURE;
- env_set_hex(argv[1], value);
+ if (w != CMD_DATA_SIZE_STR) {
+ ulong a = aval.ival;
+ ulong b = bval.ival;
+
+ switch (argv[3][0]) {
+ case '|':
+ value = a | b;
+ break;
+ case '&':
+ value = a & b;
+ break;
+ case '+':
+ value = a + b;
+ break;
+ case '^':
+ value = a ^ b;
+ break;
+ case '-':
+ value = a - b;
+ break;
+ case '*':
+ value = a * b;
+ break;
+ case '/':
+ value = a / b;
+ break;
+ case '%':
+ value = a % b;
+ break;
+ default:
+ printf("invalid op\n");
+ return 1;
+ }
+
+ env_set_hex(argv[1], value);
+ }
return 0;
}