cmd: env: Add `indirect` to indirectly set values
authorSamuel Dionne-Riel <samuel@dionne-riel.com>
Mon, 20 Dec 2021 23:31:56 +0000 (18:31 -0500)
committerTom Rini <trini@konsulko.com>
Thu, 7 Apr 2022 20:50:42 +0000 (16:50 -0400)
This allows an ergonomic-enough approximation of ${!variable} expansion.
This could be used the following way:

```
for target in ${boot_targets}; do
   env indirect target_name target_name_${target}
   # ...
done
```

Assuming `target_name_mmc0` and similar are set appropriately.

A default value can be optionally provided.

Note: this acts on environment variables, not hush variables.

Signed-off-by: Samuel Dionne-Riel <samuel@dionne-riel.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: "Marek BehĂșn" <marek.behun@nic.cz>
[trini: Don't enable by default]

cmd/Kconfig
cmd/nvedit.c

index 7bd9546..c5eb71c 100644 (file)
@@ -518,6 +518,9 @@ config CMD_NVEDIT_EFI
          If enabled, we are allowed to set/print UEFI variables using
          "env" command with "-e" option without knowing details.
 
+config CMD_NVEDIT_INDIRECT
+       bool "env indirect - Sets environment value from another"
+
 config CMD_NVEDIT_INFO
        bool "env info - print or evaluate environment information"
        help
index 3bb6e76..53e6b57 100644 (file)
@@ -1018,6 +1018,45 @@ sep_err:
 }
 #endif
 
+#if defined(CONFIG_CMD_NVEDIT_INDIRECT)
+static int do_env_indirect(struct cmd_tbl *cmdtp, int flag,
+                      int argc, char *const argv[])
+{
+       char *to = argv[1];
+       char *from = argv[2];
+       char *default_value = NULL;
+       int ret = 0;
+
+       if (argc < 3 || argc > 4) {
+               return CMD_RET_USAGE;
+       }
+
+       if (argc == 4) {
+               default_value = argv[3];
+       }
+
+       if (env_get(from) == NULL && default_value == NULL) {
+               printf("## env indirect: Environment variable for <from> (%s) does not exist.\n", from);
+
+               return CMD_RET_FAILURE;
+       }
+
+       if (env_get(from) == NULL) {
+               ret = env_set(to, default_value);
+       }
+       else {
+               ret = env_set(to, env_get(from));
+       }
+
+       if (ret == 0) {
+               return CMD_RET_SUCCESS;
+       }
+       else {
+               return CMD_RET_FAILURE;
+       }
+}
+#endif
+
 #if defined(CONFIG_CMD_NVEDIT_INFO)
 /*
  * print_env_info - print environment information
@@ -1181,6 +1220,9 @@ static struct cmd_tbl cmd_env_sub[] = {
 #if defined(CONFIG_CMD_IMPORTENV)
        U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""),
 #endif
+#if defined(CONFIG_CMD_NVEDIT_INDIRECT)
+       U_BOOT_CMD_MKENT(indirect, 3, 0, do_env_indirect, "", ""),
+#endif
 #if defined(CONFIG_CMD_NVEDIT_INFO)
        U_BOOT_CMD_MKENT(info, 3, 0, do_env_info, "", ""),
 #endif
@@ -1265,6 +1307,9 @@ static char env_help_text[] =
 #if defined(CONFIG_CMD_IMPORTENV)
        "env import [-d] [-t [-r] | -b | -c] addr [size] [var ...] - import environment\n"
 #endif
+#if defined(CONFIG_CMD_NVEDIT_INDIRECT)
+       "env indirect <to> <from> [default] - sets <to> to the value of <from>, using [default] when unset\n"
+#endif
 #if defined(CONFIG_CMD_NVEDIT_INFO)
        "env info - display environment information\n"
        "env info [-d] [-p] [-q] - evaluate environment information\n"