All of lore.kernel.org
 help / color / mirror / Atom feed
From: Artem Lapkin <email2tema@gmail.com>
To: sjg@chromium.org
Cc: trini@konsulko.com, marek.behun@nic.cz, narmstrong@baylibre.com,
	twarren@nvidia.com, andre.przywara@arm.com, u-boot@lists.denx.de,
	u-boot-amlogic@groups.io, art@khadas.com, nick@khadas.com,
	gouwa@khadas.com
Subject: [PATCH v1] env: setenv add resolve value option
Date: Tue,  2 Nov 2021 15:19:14 +0800	[thread overview]
Message-ID: <20211102071914.696963-1-art@khadas.com> (raw)

Add possibility setup env variable with additional resolving vars inside
value.

Usage examples

=> setenv a hello
=> setenv b world
=> setenv c '${a} ${b}'
=> setenv -r d '${c}! ${a}...'
=> printenv d
d=hello world! hello...

/* internal usage example */
env_resolve("d", "${c}! ${a}...");
/* d="hello world! hello..." */

Notes

Resolving works only for ${var} "bracket" and didn't workd for
"unbracket" $var

=> setenv -r d '$c! $a...'
=> printenv d
d=$c! $a...

Signed-off-by: Artem Lapkin <art@khadas.com>
---
 cmd/nvedit.c       | 42 +++++++++++++++++++++++++++++++++++++++++-
 include/_exports.h |  1 +
 include/env.h      | 11 +++++++++++
 include/exports.h  |  1 +
 4 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 3bb6e764c0..6608932dc0 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -229,6 +229,7 @@ static int _do_env_set(int flag, int argc, char *const argv[], int env_flag)
 	int   i, len;
 	char  *name, *value, *s;
 	struct env_entry e, *ep;
+	bool  resolve = 0;
 
 	debug("Initial value for argc=%d\n", argc);
 
@@ -246,6 +247,9 @@ static int _do_env_set(int flag, int argc, char *const argv[], int env_flag)
 			case 'f':		/* force */
 				env_flag |= H_FORCE;
 				break;
+			case 'r':		/* resolve */
+				resolve = 1;
+				break;
 			default:
 				return CMD_RET_USAGE;
 			}
@@ -291,6 +295,26 @@ static int _do_env_set(int flag, int argc, char *const argv[], int env_flag)
 	if (s != value)
 		*--s = '\0';
 
+	/*
+	 * deep resolve value vars
+	 */
+	if (resolve) {
+		int max_loop = 32;
+		char value2[CONFIG_SYS_CBSIZE];
+
+		do {
+			cli_simple_process_macros(value, value2, CONFIG_SYS_CBSIZE);
+			if (!strcmp(value, value2))
+				break;
+			value = realloc(value, strlen(value2));
+			if (!value) {
+				printf("## Can't realloc %d bytes\n", len);
+				return 1;
+			}
+			strcpy(value, value2);
+		} while (max_loop--);
+	}
+
 	e.key	= name;
 	e.data	= value;
 	hsearch_r(e, ENV_ENTER, &ep, &env_htab, env_flag);
@@ -304,6 +328,20 @@ static int _do_env_set(int flag, int argc, char *const argv[], int env_flag)
 	return 0;
 }
 
+int env_resolve(const char *varname, const char *varvalue)
+{
+	const char * const argv[5] = { "setenv", "-r", varname, varvalue, NULL };
+
+	/* before import into hashtable */
+	if (!(gd->flags & GD_FLG_ENV_READY))
+		return 1;
+
+	if (!varvalue || varvalue[0] == '\0')
+		return _do_env_set(0, 3, (char * const *)argv, H_PROGRAMMATIC);
+	else
+		return _do_env_set(0, 4, (char * const *)argv, H_PROGRAMMATIC);
+}
+
 int env_set(const char *varname, const char *varvalue)
 {
 	const char * const argv[4] = { "setenv", varname, varvalue, NULL };
@@ -1371,7 +1409,9 @@ U_BOOT_CMD_COMPLETE(
 	"setenv [-f] name value ...\n"
 	"    - [forcibly] set environment variable 'name' to 'value ...'\n"
 	"setenv [-f] name\n"
-	"    - [forcibly] delete environment variable 'name'",
+	"    - [forcibly] delete environment variable 'name'\n"
+	"setenv [-r] name value ...\n"
+	"    - [resolve] resolve 'value ...' to environment variable\n",
 	var_complete
 );
 
diff --git a/include/_exports.h b/include/_exports.h
index 8030d70c0b..86bc07f051 100644
--- a/include/_exports.h
+++ b/include/_exports.h
@@ -32,6 +32,7 @@
 	EXPORT_FUNC(do_reset, int, do_reset, struct cmd_tbl *,
 		    int , int , char * const [])
 	EXPORT_FUNC(env_get, char  *, env_get, const char*)
+	EXPORT_FUNC(env_resolve, int, env_resolve, const char *, const char *)
 	EXPORT_FUNC(env_set, int, env_set, const char *, const char *)
 	EXPORT_FUNC(simple_strtoul, unsigned long, simple_strtoul,
 		    const char *, char **, unsigned int)
diff --git a/include/env.h b/include/env.h
index ee5e30d036..c4efc5b7e5 100644
--- a/include/env.h
+++ b/include/env.h
@@ -133,6 +133,17 @@ int env_get_f(const char *name, char *buf, unsigned int len);
  */
 int env_get_yesno(const char *var);
 
+/**
+ * env_resolve() - resolve to environment variable
+ *
+ * Same as env_set but make deep resolve for variable
+ *
+ * @varname: Variable to adjust
+ * @value: Value to resolve for the variable, or NULL or "" to delete the variable
+ * @return 0 if OK, 1 on error
+ */
+int env_resolve(const char *varname, const char *value);
+
 /**
  * env_set() - set an environment variable
  *
diff --git a/include/exports.h b/include/exports.h
index 550cafdc7a..a54b997988 100644
--- a/include/exports.h
+++ b/include/exports.h
@@ -44,6 +44,7 @@ int vprintf(const char *, va_list);
 unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base);
 int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
 char *env_get(const char *name);
+int env_resolve(const char *varname, const char *value);
 int env_set(const char *varname, const char *value);
 long simple_strtol(const char *cp, char **endp, unsigned int base);
 int strcmp(const char *cs, const char *ct);
-- 
2.25.1


             reply	other threads:[~2021-11-02  7:19 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-02  7:19 Artem Lapkin [this message]
2021-11-02 14:58 ` [PATCH v1] env: setenv add resolve value option Simon Glass
2021-11-02 16:44 ` Tom Rini
2021-11-03  7:41   ` Art Nikpal
2021-11-05  2:02     ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211102071914.696963-1-art@khadas.com \
    --to=email2tema@gmail.com \
    --cc=andre.przywara@arm.com \
    --cc=art@khadas.com \
    --cc=gouwa@khadas.com \
    --cc=marek.behun@nic.cz \
    --cc=narmstrong@baylibre.com \
    --cc=nick@khadas.com \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=twarren@nvidia.com \
    --cc=u-boot-amlogic@groups.io \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.