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>
This commit is contained in:
Simon Glass 2020-11-01 14:15:43 -07:00 committed by Tom Rini
parent 8f4aa7ddb9
commit f66bee41ab

View File

@ -15,8 +15,19 @@
#include <log.h> #include <log.h>
#include <mapmem.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 * If the parameter starts with a '*' then assume it is a pointer to
* the value we want. * the value we want.
@ -32,26 +43,33 @@ static ulong get_arg(char *s, int w)
p = map_sysmem(addr, sizeof(uchar)); p = map_sysmem(addr, sizeof(uchar));
val = (ulong)*(uchar *)p; val = (ulong)*(uchar *)p;
unmap_sysmem(p); unmap_sysmem(p);
return val; arg.ival = val;
break;
case 2: case 2:
p = map_sysmem(addr, sizeof(ushort)); p = map_sysmem(addr, sizeof(ushort));
val = (ulong)*(ushort *)p; val = (ulong)*(ushort *)p;
unmap_sysmem(p); unmap_sysmem(p);
return val; arg.ival = val;
break;
case 4: case 4:
p = map_sysmem(addr, sizeof(u32)); p = map_sysmem(addr, sizeof(u32));
val = *(u32 *)p; val = *(u32 *)p;
unmap_sysmem(p); unmap_sysmem(p);
return val; arg.ival = val;
break;
default: default:
p = map_sysmem(addr, sizeof(ulong)); p = map_sysmem(addr, sizeof(ulong));
val = *p; val = *p;
unmap_sysmem(p); unmap_sysmem(p);
return val; arg.ival = val;
break;
} }
} else { } else {
return simple_strtoul(s, NULL, 16); arg.ival = simple_strtoul(s, NULL, 16);
} }
*argp = arg;
return 0;
} }
#ifdef CONFIG_REGEX #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, static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]) char *const argv[])
{ {
ulong a, b; struct expr_arg aval, bval;
ulong value; ulong value;
int w; 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); 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" */ /* plain assignment: "setexpr name value" */
if (argc == 3) { if (argc == 3)
env_set_hex(argv[1], a); return env_set_hex(argv[1], aval.ival);
return 0;
}
/* 5 or 6 args (6 args only with [g]sub) */ /* 5 or 6 args (6 args only with [g]sub) */
#ifdef CONFIG_REGEX #ifdef CONFIG_REGEX
@ -367,40 +384,46 @@ static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
if (strlen(argv[3]) != 1) if (strlen(argv[3]) != 1)
return CMD_RET_USAGE; return CMD_RET_USAGE;
b = get_arg(argv[4], w); if (get_arg(argv[4], w, &bval))
return CMD_RET_FAILURE;
switch (argv[3][0]) { if (w != CMD_DATA_SIZE_STR) {
case '|': ulong a = aval.ival;
value = a | b; ulong b = bval.ival;
break;
case '&': switch (argv[3][0]) {
value = a & b; case '|':
break; value = a | b;
case '+': break;
value = a + b; case '&':
break; value = a & b;
case '^': break;
value = a ^ b; case '+':
break; value = a + b;
case '-': break;
value = a - b; case '^':
break; value = a ^ b;
case '*': break;
value = a * b; case '-':
break; value = a - b;
case '/': break;
value = a / b; case '*':
break; value = a * b;
case '%': break;
value = a % b; case '/':
break; value = a / b;
default: break;
printf("invalid op\n"); case '%':
return 1; value = a % b;
break;
default:
printf("invalid op\n");
return 1;
}
env_set_hex(argv[1], value);
} }
env_set_hex(argv[1], value);
return 0; return 0;
} }