aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wordsplit.h3
-rw-r--r--src/wordsplit.c66
2 files changed, 44 insertions, 25 deletions
diff --git a/include/wordsplit.h b/include/wordsplit.h
index 0d6eef3..3451979 100644
--- a/include/wordsplit.h
+++ b/include/wordsplit.h
@@ -216,7 +216,8 @@ struct wordsplit
#define WRDSO_FAILGLOB 0x00000002
/* Allow a leading period to be matched by metacharacters. */
#define WRDSO_DOTGLOB 0x00000004
-/* Unused value: 0x00000008 */
+/* Prefer ws_getvar over lookup in ws_env, if both are supplied */
+#define WRDSO_GETVARPREF 0x00000008
/* Keep backslash in unrecognized escape sequences in words */
#define WRDSO_BSKEEP_WORD 0x00000010
/* Handle octal escapes in words */
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] == '=')
+ 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)
{
@@ -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

Return to:

Send suggestions and report system problems to the System administrator.