summaryrefslogtreecommitdiff
path: root/cmd/setexpr.c
diff options
context:
space:
mode:
authorRoland Gaudig <roland.gaudig@weidmueller.com>2021-07-23 12:29:21 +0000
committerTom Rini <trini@konsulko.com>2021-07-27 14:50:47 -0400
commitf4f8d8bb1abc79c4186ee8dc2ea536d62c6cb149 (patch)
treeffb09d738a6f68edb543be8eac0f424ec15cd4d3 /cmd/setexpr.c
parent6244cda4f32cb95f66de2a61ef728f325514f8f6 (diff)
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 <name> fmt <format> [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 <roland.gaudig@weidmueller.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'cmd/setexpr.c')
-rw-r--r--cmd/setexpr.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/cmd/setexpr.c b/cmd/setexpr.c
index e828be3970..1eb67e2eff 100644
--- a/cmd/setexpr.c
+++ b/cmd/setexpr.c
@@ -11,11 +11,15 @@
#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 <linux/sizes.h>
+#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 <op> [*]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 <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"