]> Git Repo - J-u-boot.git/blobdiff - cmd/setexpr.c
Subtree merge tag 'v6.12-dts' of dts repo [1] into dts/upstream
[J-u-boot.git] / cmd / setexpr.c
index e828be39700063b42666658a70b996b7399d6250..e111b8ba98ad7c276621aca949ccd31ba5dc12ed 100644 (file)
@@ -8,14 +8,19 @@
  * This file provides a shell like 'expr' function to return.
  */
 
-#include <common.h>
 #include <config.h>
 #include <command.h>
+#include <ctype.h>
 #include <env.h>
 #include <log.h>
 #include <malloc.h>
 #include <mapmem.h>
+#include <vsprintf.h>
+#include <linux/errno.h>
 #include <linux/sizes.h>
+#include "printf.h"
+
+#define MAX_STR_LEN 128
 
 /**
  * struct expr_arg: Holds an argument to an expression
@@ -45,7 +50,7 @@ static int get_arg(char *s, int w, struct expr_arg *argp)
                int len;
                char *str;
 
-               addr = simple_strtoul(&s[1], NULL, 16);
+               addr = hextoul(&s[1], NULL);
                switch (w) {
                case 1:
                        p = map_sysmem(addr, sizeof(uchar));
@@ -90,7 +95,7 @@ static int get_arg(char *s, int w, struct expr_arg *argp)
        } else {
                if (w == CMD_DATA_SIZE_STR)
                        return -EINVAL;
-               arg.ival = simple_strtoul(s, NULL, 16);
+               arg.ival = hextoul(s, NULL);
        }
        *argp = arg;
 
@@ -136,7 +141,7 @@ static char *memstr(const char *s1, int l1, const char *s2, int l2)
  * @olen: Length of @old excluding terminator
  * @new: New string to replace @old with
  * @nlen: Length of @new excluding terminator
- * @return pointer to immediately after the copied @new in @string, or NULL if
+ * Return: pointer to immediately after the copied @new in @string, or NULL if
  *     no replacement took place
  */
 static char *substitute(char *string, int *slen, int ssize,
@@ -211,15 +216,13 @@ int setexpr_regex_sub(char *data, uint data_size, char *nbuf, uint nbuf_size,
 
                if (res == 0) {
                        if (loop == 0) {
-                               printf("%s: No match\n", data);
-                               return 1;
+                               debug("%s: No match\n", data);
                        } else {
-                               break;
+                               debug("## MATCH ## %s\n", data);
                        }
+                       break;
                }
 
-               debug("## MATCH ## %s\n", data);
-
                if (!s)
                        return 1;
 
@@ -355,7 +358,7 @@ static int regex_sub_var(const char *name, const char *r, const char *s,
        if (ret)
                return 1;
 
-       printf("%s=%s\n", name, data);
+       debug("%s=%s\n", name, data);
 
        return env_set(name, data);
 }
@@ -370,15 +373,16 @@ static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
        int w;
 
        /*
-        * We take 3, 5, or 6 arguments:
+        * We take 3, 5, or 6 arguments, except fmt operation, which
+        * takes 4 to 8 arguments (limited by _maxargs):
         * 3 : setexpr name value
         * 5 : setexpr name val1 op val2
         *     setexpr name [g]sub r s
         * 6 : setexpr name [g]sub r s t
+        *     setexpr name fmt format [val1] [val2] [val3] [val4]
         */
 
-       /* > 6 already tested by max command args */
-       if ((argc < 3) || (argc == 4))
+       if (argc < 3)
                return CMD_RET_USAGE;
 
        w = cmd_get_data_size(argv[0], 4);
@@ -386,6 +390,24 @@ static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
        if (get_arg(argv[2], w, &aval))
                return CMD_RET_FAILURE;
 
+       /* format string assignment: "setexpr name fmt %d value" */
+       if (strcmp(argv[2], "fmt") == 0 && IS_ENABLED(CONFIG_CMD_SETEXPR_FMT)) {
+               char str[MAX_STR_LEN];
+               int result;
+
+               if (argc == 3)
+                       return CMD_RET_USAGE;
+
+               result = printf_setexpr(str, sizeof(str), argc - 3, &argv[3]);
+               if (result)
+                       return result;
+
+               return env_set(argv[1], str);
+       }
+
+       if (argc == 4 || argc > 6)
+               return CMD_RET_USAGE;
+
        /* plain assignment: "setexpr name value" */
        if (argc == 3) {
                if (w == CMD_DATA_SIZE_STR) {
@@ -495,7 +517,7 @@ static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
 }
 
 U_BOOT_CMD(
-       setexpr, 6, 0, do_setexpr,
+       setexpr, 8, 0, do_setexpr,
        "set environment variable as the result of eval expression",
        "[.b, .w, .l, .s] name [*]value1 <op> [*]value2\n"
        "    - set environment variable 'name' to the result of the evaluated\n"
@@ -505,13 +527,20 @@ U_BOOT_CMD(
        "      memory addresses (*)\n"
        "setexpr[.b, .w, .l] name [*]value\n"
        "    - load a value into a variable"
+#ifdef CONFIG_CMD_SETEXPR_FMT
+       "\n"
+       "setexpr name fmt <format> [value1] [value2] [value3] [value4]\n"
+       "    - set environment variable 'name' to the result of the bash like\n"
+       "      format string evaluation of value."
+#endif
 #ifdef CONFIG_REGEX
        "\n"
        "setexpr name gsub r s [t]\n"
        "    - 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
This page took 0.031326 seconds and 4 git commands to generate.