From 7b611ee90e1e4db531c4e3896efebfdc0743725d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Sun, 17 Oct 2021 17:36:29 +0200 Subject: env: Change env_match() to static and remove from header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function was used by other parts of U-Boot in the past when environment was read from underlying device one character at a time. This is not the case anymore. Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- cmd/nvedit.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index ddc715b4f91..742e0924afc 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -706,6 +706,21 @@ char *from_env(const char *envvar) return ret; } +static int env_match(uchar *s1, int i2) +{ + if (s1 == NULL) + return -1; + + while (*s1 == env_get_char(i2++)) + if (*s1++ == '=') + return i2; + + if (*s1 == '\0' && env_get_char(i2-1) == '=') + return i2; + + return -1; +} + /* * Look up variable from environment for restricted C runtime env. */ @@ -816,21 +831,6 @@ static int do_env_select(struct cmd_tbl *cmdtp, int flag, int argc, #endif /* CONFIG_SPL_BUILD */ -int env_match(uchar *s1, int i2) -{ - if (s1 == NULL) - return -1; - - while (*s1 == env_get_char(i2++)) - if (*s1++ == '=') - return i2; - - if (*s1 == '\0' && env_get_char(i2-1) == '=') - return i2; - - return -1; -} - #ifndef CONFIG_SPL_BUILD static int do_env_default(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -- cgit v1.2.3 From 52f9ed34cb3768663ee9c2e5d980143e8ac783a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Sun, 17 Oct 2021 17:36:30 +0200 Subject: env: Inline env_get_char() into its only user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function is a relic from the past when environment was read from underlying device one character at a time. It is used only in the case when getting an environemnt variable prior relocation, and the function is simple enough to be inlined there. Since env_get_char() is being changed to simple access to an array, we can drop the failing cases and simplify the code (this could have been done before, since env_get_char() did not fail even before). Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- cmd/nvedit.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 742e0924afc..3952deda1b3 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -706,16 +706,16 @@ char *from_env(const char *envvar) return ret; } -static int env_match(uchar *s1, int i2) +static int env_match(const char *env, const char *s1, int i2) { if (s1 == NULL) return -1; - while (*s1 == env_get_char(i2++)) + while (*s1 == env[i2++]) if (*s1++ == '=') return i2; - if (*s1 == '\0' && env_get_char(i2-1) == '=') + if (*s1 == '\0' && env[i2-1] == '=') return i2; return -1; @@ -726,28 +726,28 @@ static int env_match(uchar *s1, int i2) */ int env_get_f(const char *name, char *buf, unsigned len) { - int i, nxt, c; + const char *env; + int i, nxt; - for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { + if (gd->env_valid == ENV_INVALID) + env = (const char *)default_environment; + else + env = (const char *)gd->env_addr; + + for (i = 0; env[i] != '\0'; i = nxt + 1) { int val, n; - for (nxt = i; (c = env_get_char(nxt)) != '\0'; ++nxt) { - if (c < 0) - return c; + for (nxt = i; env[nxt] != '\0'; ++nxt) if (nxt >= CONFIG_ENV_SIZE) return -1; - } - val = env_match((uchar *)name, i); + val = env_match(env, name, i); if (val < 0) continue; /* found; copy out */ for (n = 0; n < len; ++n, ++buf) { - c = env_get_char(val++); - if (c < 0) - return c; - *buf = c; + *buf = env[val++]; if (*buf == '\0') return n; } -- cgit v1.2.3 From eff73b2eed28389805e8dda6632f6c5f29b3e9b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Sun, 17 Oct 2021 17:36:31 +0200 Subject: env: Use string pointer instead of indexes in env_get_f() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we no longer use env_get_char() to access n-th character of linearized environment data, but rather access the arrays themselves, we can convert the iteration to use string pointers instead of position indexes. Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- cmd/nvedit.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 3952deda1b3..f395d2893a2 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -706,19 +706,19 @@ char *from_env(const char *envvar) return ret; } -static int env_match(const char *env, const char *s1, int i2) +static const char *env_match(const char *p, const char *s1) { if (s1 == NULL) - return -1; + return NULL; - while (*s1 == env[i2++]) + while (*s1 == *p++) if (*s1++ == '=') - return i2; + return p; - if (*s1 == '\0' && env[i2-1] == '=') - return i2; + if (*s1 == '\0' && p[-1] == '=') + return p; - return -1; + return NULL; } /* @@ -726,28 +726,28 @@ static int env_match(const char *env, const char *s1, int i2) */ int env_get_f(const char *name, char *buf, unsigned len) { - const char *env; - int i, nxt; + const char *env, *p, *nxt; if (gd->env_valid == ENV_INVALID) env = (const char *)default_environment; else env = (const char *)gd->env_addr; - for (i = 0; env[i] != '\0'; i = nxt + 1) { - int val, n; + for (p = env; *p != '\0'; p = nxt + 1) { + const char *value; + int n; - for (nxt = i; env[nxt] != '\0'; ++nxt) - if (nxt >= CONFIG_ENV_SIZE) + for (nxt = p; *nxt != '\0'; ++nxt) + if (nxt - env >= CONFIG_ENV_SIZE) return -1; - val = env_match(env, name, i); - if (val < 0) + value = env_match(p, name); + if (value == NULL) continue; /* found; copy out */ for (n = 0; n < len; ++n, ++buf) { - *buf = env[val++]; + *buf = *value++; if (*buf == '\0') return n; } -- cgit v1.2.3 From d1bca8d2a18eb4a850c0ecbc9327eb3dfa5df5e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Sun, 17 Oct 2021 17:36:32 +0200 Subject: env: Use better name for variable in env_get_f() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `nxt` variable actually points to the terminating null-byte of the current env var, and the next env var is at `nxt + 1`, not `nxt`. So a better name for this variable is `end`. Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- cmd/nvedit.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index f395d2893a2..5b1d4c24486 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -726,19 +726,19 @@ static const char *env_match(const char *p, const char *s1) */ int env_get_f(const char *name, char *buf, unsigned len) { - const char *env, *p, *nxt; + const char *env, *p, *end; if (gd->env_valid == ENV_INVALID) env = (const char *)default_environment; else env = (const char *)gd->env_addr; - for (p = env; *p != '\0'; p = nxt + 1) { + for (p = env; *p != '\0'; p = end + 1) { const char *value; int n; - for (nxt = p; *nxt != '\0'; ++nxt) - if (nxt - env >= CONFIG_ENV_SIZE) + for (end = p; *end != '\0'; ++end) + if (end - env >= CONFIG_ENV_SIZE) return -1; value = env_match(p, name); -- cgit v1.2.3 From 6ba4473fb757e7606a4224d87774294c9d60d2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Sun, 17 Oct 2021 17:36:33 +0200 Subject: env: Don't match empty variable name in env_match() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do we really allow zero-length variable name? I guess not. Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- cmd/nvedit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 5b1d4c24486..8d53579d92e 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -708,7 +708,7 @@ char *from_env(const char *envvar) static const char *env_match(const char *p, const char *s1) { - if (s1 == NULL) + if (s1 == NULL || *s1 == '\0') return NULL; while (*s1 == *p++) -- cgit v1.2.3 From 6b6e3eeba9f96b5d908a9b46b7bb25e76109a0c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Sun, 17 Oct 2021 17:36:34 +0200 Subject: env: Early return from env_get_f() on NULL name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test non-NULL name immediately, not in env_match(). Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- cmd/nvedit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 8d53579d92e..063cc762823 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -708,9 +708,6 @@ char *from_env(const char *envvar) static const char *env_match(const char *p, const char *s1) { - if (s1 == NULL || *s1 == '\0') - return NULL; - while (*s1 == *p++) if (*s1++ == '=') return p; @@ -728,6 +725,9 @@ int env_get_f(const char *name, char *buf, unsigned len) { const char *env, *p, *end; + if (name == NULL || *name == '\0') + return -1; + if (gd->env_valid == ENV_INVALID) env = (const char *)default_environment; else -- cgit v1.2.3 From 3112ce0ce8195880aec5e9373434a85e21c3e1af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Sun, 17 Oct 2021 17:36:35 +0200 Subject: env: Make return value of env_get_f() behave like sprintf() on success MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the env_get_f() function's return value behaves weirdly: it returns the number of bytes written into `buf`, but whether this is excluding the terminating NULL-byte or including it depends on whether there was enough space in `buf`. Change the function to always return the actual length of the value of the environment variable (excluding the terminating NULL-byte) on success. This makes it behave like sprintf(). All users of this function in U-Boot are compatible with this change. Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- cmd/nvedit.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 063cc762823..527b522e9e9 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -735,7 +735,7 @@ int env_get_f(const char *name, char *buf, unsigned len) for (p = env; *p != '\0'; p = end + 1) { const char *value; - int n; + int n, res; for (end = p; *end != '\0'; ++end) if (end - env >= CONFIG_ENV_SIZE) @@ -745,11 +745,13 @@ int env_get_f(const char *name, char *buf, unsigned len) if (value == NULL) continue; + res = end - value; + /* found; copy out */ for (n = 0; n < len; ++n, ++buf) { *buf = *value++; if (*buf == '\0') - return n; + return res; } if (n) @@ -758,7 +760,7 @@ int env_get_f(const char *name, char *buf, unsigned len) printf("env_buf [%u bytes] too small for value of \"%s\"\n", len, name); - return n; + return res; } return -1; -- cgit v1.2.3 From a473766cce44882237e567bcd58f7559ecdd0440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Sun, 17 Oct 2021 17:36:36 +0200 Subject: env: Use memcpy() instead of ad-hoc code to copy variable value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copy the value of the found variable into given buffer with memcpy() instead of ad-hoc code. Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- cmd/nvedit.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 527b522e9e9..ffcfb55f105 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -735,7 +735,7 @@ int env_get_f(const char *name, char *buf, unsigned len) for (p = env; *p != '\0'; p = end + 1) { const char *value; - int n, res; + unsigned res; for (end = p; *end != '\0'; ++end) if (end - env >= CONFIG_ENV_SIZE) @@ -746,20 +746,14 @@ int env_get_f(const char *name, char *buf, unsigned len) continue; res = end - value; + memcpy(buf, value, min(len, res + 1)); - /* found; copy out */ - for (n = 0; n < len; ++n, ++buf) { - *buf = *value++; - if (*buf == '\0') - return res; + if (len <= res) { + buf[len - 1] = '\0'; + printf("env_buf [%u bytes] too small for value of \"%s\"\n", + len, name); } - if (n) - *--buf = '\0'; - - printf("env_buf [%u bytes] too small for value of \"%s\"\n", - len, name); - return res; } -- cgit v1.2.3 From a80652ebb394abfd508feb38090228f5e5290d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Sun, 17 Oct 2021 17:36:37 +0200 Subject: env: Simplify env_match() and inline into env_get_f() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the past the env_match() function was used to match envs with - name, i.e. string "name" - variable assignment, i.e. string "name=other_value" The latter is not the case anymore, since the env_match() function is now used only in env_get_f(), and so we can simplify the function into a simple strncmp() with an additional comparison to '='. Let's do this, and since the resulting function is quite simple, let's also inline its code into env_get_f(). Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- cmd/nvedit.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index ffcfb55f105..272d0c7718d 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -706,28 +706,19 @@ char *from_env(const char *envvar) return ret; } -static const char *env_match(const char *p, const char *s1) -{ - while (*s1 == *p++) - if (*s1++ == '=') - return p; - - if (*s1 == '\0' && p[-1] == '=') - return p; - - return NULL; -} - /* * Look up variable from environment for restricted C runtime env. */ int env_get_f(const char *name, char *buf, unsigned len) { const char *env, *p, *end; + size_t name_len; if (name == NULL || *name == '\0') return -1; + name_len = strlen(name); + if (gd->env_valid == ENV_INVALID) env = (const char *)default_environment; else @@ -741,9 +732,9 @@ int env_get_f(const char *name, char *buf, unsigned len) if (end - env >= CONFIG_ENV_SIZE) return -1; - value = env_match(p, name); - if (value == NULL) + if (strncmp(name, p, name_len) || p[name_len] != '=') continue; + value = &p[name_len + 1]; res = end - value; memcpy(buf, value, min(len, res + 1)); -- cgit v1.2.3 From f231566475c545de476a3bf5f596c246c52511aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Sun, 17 Oct 2021 17:36:38 +0200 Subject: env: Move non-cli env functions to env/common.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the following functions from cmd/nvedit.c to env/common.c: env_set_ulong() env_set_hex() env_get_hex() eth_env_get_enetaddr() eth_env_set_enetaddr() env_get() from_env() env_get_f() env_get_ulong() since these functions are not specific for U-Boot's CLI. We leave env_set() in cmd/nvedit.c, since it calls _do_env_set(), which is a static function in that file. Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- cmd/nvedit.c | 175 ----------------------------------------------------------- 1 file changed, 175 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 272d0c7718d..3bb6e764c08 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -38,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -320,69 +318,6 @@ int env_set(const char *varname, const char *varvalue) return _do_env_set(0, 3, (char * const *)argv, H_PROGRAMMATIC); } -/** - * Set an environment variable to an integer value - * - * @param varname Environment variable to set - * @param value Value to set it to - * @return 0 if ok, 1 on error - */ -int env_set_ulong(const char *varname, ulong value) -{ - /* TODO: this should be unsigned */ - char *str = simple_itoa(value); - - return env_set(varname, str); -} - -/** - * Set an environment variable to an value in hex - * - * @param varname Environment variable to set - * @param value Value to set it to - * @return 0 if ok, 1 on error - */ -int env_set_hex(const char *varname, ulong value) -{ - char str[17]; - - sprintf(str, "%lx", value); - return env_set(varname, str); -} - -ulong env_get_hex(const char *varname, ulong default_val) -{ - const char *s; - ulong value; - char *endp; - - s = env_get(varname); - if (s) - value = hextoul(s, &endp); - if (!s || endp == s) - return default_val; - - return value; -} - -int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr) -{ - string_to_enetaddr(env_get(name), enetaddr); - return is_valid_ethaddr(enetaddr); -} - -int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr) -{ - char buf[ARP_HLEN_ASCII + 1]; - - if (eth_env_get_enetaddr(name, (uint8_t *)buf)) - return -EEXIST; - - sprintf(buf, "%pM", enetaddr); - - return env_set(name, buf); -} - #ifndef CONFIG_SPL_BUILD static int do_env_set(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) @@ -661,117 +596,7 @@ static int do_env_edit(struct cmd_tbl *cmdtp, int flag, int argc, } } #endif /* CONFIG_CMD_EDITENV */ -#endif /* CONFIG_SPL_BUILD */ -/* - * Look up variable from environment, - * return address of storage for that variable, - * or NULL if not found - */ -char *env_get(const char *name) -{ - if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */ - struct env_entry e, *ep; - - WATCHDOG_RESET(); - - e.key = name; - e.data = NULL; - hsearch_r(e, ENV_FIND, &ep, &env_htab, 0); - - return ep ? ep->data : NULL; - } - - /* restricted capabilities before import */ - if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0) - return (char *)(gd->env_buf); - - return NULL; -} - -/* - * Like env_get, but prints an error if envvar isn't defined in the - * environment. It always returns what env_get does, so it can be used in - * place of env_get without changing error handling otherwise. - */ -char *from_env(const char *envvar) -{ - char *ret; - - ret = env_get(envvar); - - if (!ret) - printf("missing environment variable: %s\n", envvar); - - return ret; -} - -/* - * Look up variable from environment for restricted C runtime env. - */ -int env_get_f(const char *name, char *buf, unsigned len) -{ - const char *env, *p, *end; - size_t name_len; - - if (name == NULL || *name == '\0') - return -1; - - name_len = strlen(name); - - if (gd->env_valid == ENV_INVALID) - env = (const char *)default_environment; - else - env = (const char *)gd->env_addr; - - for (p = env; *p != '\0'; p = end + 1) { - const char *value; - unsigned res; - - for (end = p; *end != '\0'; ++end) - if (end - env >= CONFIG_ENV_SIZE) - return -1; - - if (strncmp(name, p, name_len) || p[name_len] != '=') - continue; - value = &p[name_len + 1]; - - res = end - value; - memcpy(buf, value, min(len, res + 1)); - - if (len <= res) { - buf[len - 1] = '\0'; - printf("env_buf [%u bytes] too small for value of \"%s\"\n", - len, name); - } - - return res; - } - - return -1; -} - -/** - * Decode the integer value of an environment variable and return it. - * - * @param name Name of environment variable - * @param base Number base to use (normally 10, or 16 for hex) - * @param default_val Default value to return if the variable is not - * found - * @return the decoded value, or default_val if not found - */ -ulong env_get_ulong(const char *name, int base, ulong default_val) -{ - /* - * We can use env_get() here, even before relocation, since the - * environment variable value is an integer and thus short. - */ - const char *str = env_get(name); - - return str ? simple_strtoul(str, NULL, base) : default_val; -} - -#ifndef CONFIG_SPL_BUILD #if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE) static int do_env_save(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -- cgit v1.2.3