aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-06-13 14:20:20 +0300
committerSergey Poznyakoff <gray@gnu.org>2019-06-13 14:20:20 +0300
commit12304127b52650588877f00b0c4b32dae083e852 (patch)
treee6a2fa21b66d16a82a7913933b88bd091f633dc6 /src
parentdbe318987cf3a36fe63893205d3df0dc3be7fa4a (diff)
downloadgrecs-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.c66
1 files changed, 42 insertions, 24 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c
index d01fd43..9179a87 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -1031,60 +1031,78 @@ find_closing_paren (const char *str, size_t i, size_t len, size_t *poff,
break;
}
}
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 */
for (i = 0; wsp->ws_env[i]; i++)
{
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++)
{
size_t j;
const char *var = wsp->ws_env[i];
for (j = 0; j < len; j++)
if (name[j] != var[j])
break;
if (j == len && var[j] == '=')
+ 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)
{
- *ret = var + j + 1;
+ 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)
{
int n = (wsp->ws_flags & WRDSF_ENV_KV) ? 2 : 1;
char *v;
@@ -1353,13 +1371,12 @@ static int
expvar (struct wordsplit *wsp, const char *str, size_t len,
struct wordsplit_node **ptail, const char **pend, int flg)
{
size_t i = 0;
const char *defstr = NULL;
char *value;
- const char *vptr;
struct wordsplit_node *newnode;
const char *start = str - 1;
int rc;
struct wordsplit ws;
int is_param = 0;
long param_idx = 0;
@@ -1494,28 +1511,29 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
else
rc = WRDSE_UNDEF;
}
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
&& (!value || value[0] == 0)
&& defstr && defstr[-1] == ':')
{

Return to:

Send suggestions and report system problems to the System administrator.