[PATCH v3 4/4] cmd/setexpr: support concatenation of direct strings
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Mon Feb 3 16:10:29 CET 2025
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 at canonical.com>
---
v3:
no change
v2:
Update the commit message to indicate that a bug is corrected.
---
cmd/setexpr.c | 54 ++++++++++++++++++++++++++++++++--------------
test/cmd/setexpr.c | 7 +++++-
2 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/cmd/setexpr.c b/cmd/setexpr.c
index e111b8ba98a..c45fa85c887 100644
--- a/cmd/setexpr.c
+++ b/cmd/setexpr.c
@@ -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)
{
struct expr_arg arg;
+ int ret;
/*
* 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 addr;
ulong val;
- int len;
- char *str;
addr = hextoul(&s[1], NULL);
switch (w) {
@@ -66,18 +92,10 @@ static int get_arg(char *s, int w, struct expr_arg *argp)
break;
case CMD_DATA_SIZE_STR:
p = map_sysmem(addr, SZ_64K);
-
- /* 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';
+ ret = arg_set_str(p, &arg);
unmap_sysmem(p);
- arg.sval = str;
+ if (ret)
+ return ret;
break;
case 4:
p = map_sysmem(addr, sizeof(u32));
@@ -93,9 +111,13 @@ static int get_arg(char *s, int w, struct expr_arg *argp)
break;
}
} else {
- if (w == CMD_DATA_SIZE_STR)
- return -EINVAL;
- arg.ival = hextoul(s, NULL);
+ if (w == CMD_DATA_SIZE_STR) {
+ ret = arg_set_str(s, &arg);
+ if (ret)
+ return ret;
+ } else {
+ arg.ival = hextoul(s, NULL);
+ }
}
*argp = arg;
diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c
index 650fbc8ebee..5e9b577fe36 100644
--- a/test/cmd/setexpr.c
+++ b/test/cmd/setexpr.c
@@ -303,7 +303,8 @@ static int setexpr_test_str(struct unit_test_state *uts)
memset(buf, '\xff', BUF_SIZE);
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");
ut_assertok(env_set("fred", "12345"));
@@ -321,6 +322,10 @@ static int setexpr_test_str_oper(struct unit_test_state *uts)
{
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);
memset(buf, '\xff', BUF_SIZE);
strcpy(buf, "hello");
--
2.47.1
More information about the U-Boot
mailing list