]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
cmd: setexpr: fix no matching string in gsub return empty value
authorMassimiliano Minella <massimiliano.minella@se.com>
Thu, 8 Feb 2024 14:58:27 +0000 (15:58 +0100)
committerTom Rini <trini@konsulko.com>
Sat, 2 Mar 2024 17:26:19 +0000 (12:26 -0500)
In gsub, when the destination string is empty, the string 't' is
provided and the regular expression doesn't match, then the final result
is an empty string.

Example:

=> echo ${foo}

=> setenv foo
=> setexpr foo gsub e a bar
=> echo ${foo}

=>

The variable ${foo} should contain "bar" and the lack of match shouldn't
be considered an error.

This patch fixes the erroneous behavior by removing the return
statement and breaking out of the loop in case of lack of match.

Also add a test for the no match case.

Signed-off-by: Massimiliano Minella <massimiliano.minella@se.com>
cmd/setexpr.c
doc/usage/cmd/setexpr.rst
test/cmd/setexpr.c

index 233471f6cb7550203419ca257a75d24544194078..ab76824a32bbee54690ea4302785f6aa77e43eda 100644 (file)
@@ -216,14 +216,12 @@ int setexpr_regex_sub(char *data, uint data_size, char *nbuf, uint nbuf_size,
                if (res == 0) {
                        if (loop == 0) {
                                debug("%s: No match\n", data);
-                               return 1;
                        } else {
-                               break;
+                               debug("## MATCH ## %s\n", data);
                        }
+                       break;
                }
 
-               debug("## MATCH ## %s\n", data);
-
                if (!s)
                        return 1;
 
@@ -540,7 +538,8 @@ U_BOOT_CMD(
        "    - For each substring matching the regular expression <r> in the\n"
        "      string <t>, substitute the string <s>.  The result is\n"
        "      assigned to <name>.  If <t> is not supplied, use the old\n"
-       "      value of <name>\n"
+       "      value of <name>. If no substring matching <r> is found in <t>,\n"
+       "      assign <t> to <name>.\n"
        "setexpr name sub r s [t]\n"
        "    - Just like gsub(), but replace only the first matching substring"
 #endif
index d245a13ca88b5300ab83197679de052515af5941..593a0ea91e15cdce503c98c3fb8ee8e56e48c15b 100644 (file)
@@ -39,6 +39,7 @@ setexpr name gsub <r> <s> [<t>]
      string <t>, substitute the string <s>.
      The result is assigned to <name>.
      If <t> is not supplied, use the old value of <name>.
+     If no substring matching <r> is found in <t>, assign <t> to <name>.
 
 setexpr name sub <r> <s> [<t>]
      Just like gsub(), but replace only the first matching substring
index 312593e1e32b6d3914a7bbbc4a4853dd4eb0df4b..ee329e94b85b43f5b13d977d48fb4d03510e0d4a 100644 (file)
@@ -179,6 +179,16 @@ static int setexpr_test_regex(struct unit_test_state *uts)
        val = env_get("mary");
        ut_asserteq_str("this is a test", val);
 
+       /* No match */
+       ut_assertok(run_command("setenv fred 'this is a test'", 0));
+       ut_assertok(run_command("setenv mary ''", 0));
+       ut_assertok(run_command("setexpr fred gsub us is \"${fred}\"", 0));
+       ut_assertok(run_command("setexpr mary gsub us is \"${fred}\"", 0));
+       val = env_get("fred");
+       ut_asserteq_str("this is a test", val);
+       val = env_get("mary");
+       ut_asserteq_str("this is a test", val);
+
        unmap_sysmem(buf);
 
        return 0;