summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2025-02-03 16:10:29 +0100
committerTom Rini <trini@konsulko.com>2025-02-07 13:35:23 -0600
commitaf7eca24a78b1419656d618463f1eabe297fdb2f (patch)
tree7b12ea285a455fdbd417c1fa1aea062a65fde2f4
parentd4265cdcd57c1975d4e756ab1778c837acc9776c (diff)
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>
-rw-r--r--cmd/setexpr.c54
-rw-r--r--test/cmd/setexpr.c7
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");