mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-08-07 15:56:59 +02:00
cmd/setexpr: support concatenation of direct strings
The setexpr.s command allows to concatenate two strings. According to the description in doc/usage/cmd/setexpr.rst the parameters value1 and value2 can be either direct values or pointers to a memory location holding the values. Unfortunately `setexpr.s <value1> + <value2>` fails if any of the values is a direct value. $? is set to false. * Add support for direct values in setexpr.s. * Correct the unit test for "setexpr.s fred 0". * Add a new unit test for "setexpr.s fred '1' + '3'" giving '13'. Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
This commit is contained in:
parent
d4265cdcd5
commit
af7eca24a7
@ -35,9 +35,37 @@ struct expr_arg {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* arg_set_str() - copy string to expression argument
|
||||||
|
*
|
||||||
|
* The string is truncated to 64 KiB plus NUL terminator.
|
||||||
|
*
|
||||||
|
* @p: pointer to string
|
||||||
|
* @argp: pointer to expression argument
|
||||||
|
* Return: 0 on success, -ENOMEM if out of memory
|
||||||
|
*/
|
||||||
|
static int arg_set_str(void *p, struct expr_arg *argp)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
/* Maximum string length of 64 KiB plus NUL terminator */
|
||||||
|
len = strnlen((char *)p, SZ_64K) + 1;
|
||||||
|
str = malloc(len);
|
||||||
|
if (!str) {
|
||||||
|
printf("Out of memory\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
memcpy(str, p, len);
|
||||||
|
str[len - 1] = '\0';
|
||||||
|
argp->sval = str;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_arg(char *s, int w, struct expr_arg *argp)
|
static int get_arg(char *s, int w, struct expr_arg *argp)
|
||||||
{
|
{
|
||||||
struct expr_arg arg;
|
struct expr_arg arg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
@ -47,8 +75,6 @@ static int get_arg(char *s, int w, struct expr_arg *argp)
|
|||||||
ulong *p;
|
ulong *p;
|
||||||
ulong addr;
|
ulong addr;
|
||||||
ulong val;
|
ulong val;
|
||||||
int len;
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
addr = hextoul(&s[1], NULL);
|
addr = hextoul(&s[1], NULL);
|
||||||
switch (w) {
|
switch (w) {
|
||||||
@ -66,18 +92,10 @@ static int get_arg(char *s, int w, struct expr_arg *argp)
|
|||||||
break;
|
break;
|
||||||
case CMD_DATA_SIZE_STR:
|
case CMD_DATA_SIZE_STR:
|
||||||
p = map_sysmem(addr, SZ_64K);
|
p = map_sysmem(addr, SZ_64K);
|
||||||
|
ret = arg_set_str(p, &arg);
|
||||||
/* Maximum string length of 64KB plus terminator */
|
|
||||||
len = strnlen((char *)p, SZ_64K) + 1;
|
|
||||||
str = malloc(len);
|
|
||||||
if (!str) {
|
|
||||||
printf("Out of memory\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
memcpy(str, p, len);
|
|
||||||
str[len - 1] = '\0';
|
|
||||||
unmap_sysmem(p);
|
unmap_sysmem(p);
|
||||||
arg.sval = str;
|
if (ret)
|
||||||
|
return ret;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
p = map_sysmem(addr, sizeof(u32));
|
p = map_sysmem(addr, sizeof(u32));
|
||||||
@ -93,9 +111,13 @@ static int get_arg(char *s, int w, struct expr_arg *argp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (w == CMD_DATA_SIZE_STR)
|
if (w == CMD_DATA_SIZE_STR) {
|
||||||
return -EINVAL;
|
ret = arg_set_str(s, &arg);
|
||||||
arg.ival = hextoul(s, NULL);
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
arg.ival = hextoul(s, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*argp = arg;
|
*argp = arg;
|
||||||
|
|
||||||
|
@ -303,7 +303,8 @@ static int setexpr_test_str(struct unit_test_state *uts)
|
|||||||
memset(buf, '\xff', BUF_SIZE);
|
memset(buf, '\xff', BUF_SIZE);
|
||||||
|
|
||||||
ut_assertok(env_set("fred", "x"));
|
ut_assertok(env_set("fred", "x"));
|
||||||
ut_asserteq(1, run_command("setexpr.s fred 0", 0));
|
ut_asserteq(0, run_command("setexpr.s fred 0", 0));
|
||||||
|
ut_asserteq_str("0", env_get("fred"));
|
||||||
|
|
||||||
strcpy(buf, "hello");
|
strcpy(buf, "hello");
|
||||||
ut_assertok(env_set("fred", "12345"));
|
ut_assertok(env_set("fred", "12345"));
|
||||||
@ -321,6 +322,10 @@ static int setexpr_test_str_oper(struct unit_test_state *uts)
|
|||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
|
/* Test concatenation of strings */
|
||||||
|
ut_assertok(run_command("setexpr.s fred '1' + '3'", 0));
|
||||||
|
ut_asserteq_str("13", env_get("fred"));
|
||||||
|
|
||||||
buf = map_sysmem(0, BUF_SIZE);
|
buf = map_sysmem(0, BUF_SIZE);
|
||||||
memset(buf, '\xff', BUF_SIZE);
|
memset(buf, '\xff', BUF_SIZE);
|
||||||
strcpy(buf, "hello");
|
strcpy(buf, "hello");
|
||||||
|
Loading…
Reference in New Issue
Block a user