diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-06-13 14:20:20 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-06-13 14:20:20 +0300 |
commit | 12304127b52650588877f00b0c4b32dae083e852 (patch) | |
tree | e6a2fa21b66d16a82a7913933b88bd091f633dc6 /src | |
parent | dbe318987cf3a36fe63893205d3df0dc3be7fa4a (diff) | |
download | grecs-12304127b52650588877f00b0c4b32dae083e852.tar.gz grecs-12304127b52650588877f00b0c4b32dae083e852.tar.bz2 |
wordsplit: configurable order of lookups if both WRDSF_ENV and WRDSF_GETVAR are set
* lib/wordsplit.h (WRDSO_GETVARPREF): New option.
* lib/wordsplit.c (wordsplit_find_env): Rewrite as wsplt_env_lookup
wsplt_env_getvar): New function.
(expvar): Select preference of wsplt_env_lookup vs. wsplt_env_getvar
depending on the value if WRDSO_GETVARPREF option.
Diffstat (limited to 'src')
-rw-r--r-- | src/wordsplit.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c index d01fd43..9179a87 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c @@ -1034,15 +1034,13 @@ find_closing_paren (const char *str, size_t i, size_t len, size_t *poff, return 1; } -static int -wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len, - char const **ret) +static char const * +wsplt_env_find (struct wordsplit *wsp, const char *name, size_t len) { size_t i; - if (!(wsp->ws_flags & WRDSF_ENV)) - return WRDSE_UNDEF; - + if (!wsp->ws_env) + return NULL; if (wsp->ws_flags & WRDSF_ENV_KV) { /* A key-value pair environment */ @@ -1050,17 +1048,14 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len, { size_t elen = strlen (wsp->ws_env[i]); if (elen == len && memcmp (wsp->ws_env[i], name, elen) == 0) - { - *ret = wsp->ws_env[i + 1]; - return WRDSE_OK; - } + return wsp->ws_env[i + 1]; /* Skip the value. Break the loop if it is NULL. */ i++; if (wsp->ws_env[i] == NULL) break; } } - else if (wsp->ws_env) + else { /* Usual (A=B) environment. */ for (i = 0; wsp->ws_env[i]; i++) @@ -1072,16 +1067,39 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len, if (name[j] != var[j]) break; if (j == len && var[j] == '=') - { - *ret = var + j + 1; - return WRDSE_OK; - } + return var + j + 1; + } + } + return NULL; +} + +static int +wsplt_env_lookup (struct wordsplit *wsp, const char *name, size_t len, + char **ret) +{ + if (wsp->ws_flags & WRDSF_ENV) + { + char const *val = wsplt_env_find (wsp, name, len); + if (val) + { + char *retval = strdup (val); + if (!retval) + return WRDSE_NOSPACE; + *ret = retval; + return WRDSE_OK; } } return WRDSE_UNDEF; } static int +wsplt_env_getvar (struct wordsplit *wsp, const char *name, size_t len, + char **ret) +{ + return wsp->ws_getvar (ret, name, len, wsp->ws_closure); +} + +static int wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen, char const *value) { @@ -1356,7 +1374,6 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, size_t i = 0; const char *defstr = NULL; char *value; - const char *vptr; struct wordsplit_node *newnode; const char *start = str - 1; int rc; @@ -1497,22 +1514,23 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, } else { - rc = wordsplit_find_env (wsp, str, i, &vptr); - if (rc == WRDSE_OK) + if (wsp->ws_flags & WRDSF_GETVAR) { - if (vptr) + if (wsp->ws_options & WRDSO_GETVARPREF) { - value = strdup (vptr); - if (!value) - rc = WRDSE_NOSPACE; + rc = wsplt_env_getvar (wsp, str, i, &value); + if (rc == WRDSE_UNDEF) + rc = wsplt_env_lookup (wsp, str, i, &value); } else - rc = WRDSE_UNDEF; + { + rc = wsplt_env_lookup (wsp, str, i, &value); + if (rc == WRDSE_UNDEF) + rc = wsplt_env_getvar (wsp, str, i, &value); + } } - else if (wsp->ws_flags & WRDSF_GETVAR) - rc = wsp->ws_getvar (&value, str, i, wsp->ws_closure); else - rc = WRDSE_UNDEF; + rc = wsplt_env_lookup (wsp, str, i, &value); } if (rc == WRDSE_OK |