mirror of
git://git.gnu.org.ua/wordsplit.git
synced 2025-04-25 16:19:54 +03:00
Configurable order of lookups if both WRDSF_ENV and WRDSF_GETVAR are set
* src/wordsplit.h (WRDSO_GETVARPREF): New option. * src/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.
This commit is contained in:
parent
188bbb90d6
commit
f00da62cde
2 changed files with 46 additions and 27 deletions
|
@ -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 */
|
||||
|
|
|
@ -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,15 +1067,38 @@ 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue