]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
cmd/setexpr: support concatenation of direct strings
authorHeinrich Schuchardt <heinrich.schuchardt@canonical.com>
Mon, 3 Feb 2025 15:10:29 +0000 (16:10 +0100)
committerTom Rini <trini@konsulko.com>
Fri, 7 Feb 2025 19:35:23 +0000 (13:35 -0600)
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>
cmd/setexpr.c
test/cmd/setexpr.c

index e111b8ba98ad7c276621aca949ccd31ba5dc12ed..c45fa85c887e25f34d39ab5a3ecddf2272b2ae37 100644 (file)
@@ -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;
 
index 650fbc8ebee6fb267b910159e1b842ee7ffa1631..5e9b577fe3689f17b70a76b606f2858c517bd9c0 100644 (file)
@@ -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");