From f4f8d8bb1abc79c4186ee8dc2ea536d62c6cb149 Mon Sep 17 00:00:00 2001 From: Roland Gaudig Date: Fri, 23 Jul 2021 12:29:21 +0000 Subject: cmd: setexpr: add format string handling Add format string handling operator to the setexpr command. It allows to use C or Bash like format string expressions to be evaluated with the result being stored inside the environment variable name. setexpr fmt [value]... The following example setexpr foo fmt "%d, 0x%x" 0x100 ff will result in $foo being set to "256, 0xff". Signed-off-by: Roland Gaudig Reviewed-by: Simon Glass --- cmd/setexpr.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'cmd/setexpr.c') diff --git a/cmd/setexpr.c b/cmd/setexpr.c index e828be39700..1eb67e2effb 100644 --- a/cmd/setexpr.c +++ b/cmd/setexpr.c @@ -11,11 +11,15 @@ #include #include #include +#include #include #include #include #include #include +#include "printf.h" + +#define MAX_STR_LEN 128 /** * struct expr_arg: Holds an argument to an expression @@ -370,15 +374,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 +391,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 +518,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 [*]value2\n" " - set environment variable 'name' to the result of the evaluated\n" @@ -505,6 +528,12 @@ 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 [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" -- cgit