aboutsummaryrefslogtreecommitdiff
path: root/wordsplit.c
diff options
context:
space:
mode:
Diffstat (limited to 'wordsplit.c')
-rw-r--r--wordsplit.c119
1 files changed, 60 insertions, 59 deletions
diff --git a/wordsplit.c b/wordsplit.c
index d3ec9e1..99a8b4f 100644
--- a/wordsplit.c
+++ b/wordsplit.c
@@ -52,7 +52,14 @@
#define ISPRINT(c) (' ' <= ((unsigned) (c)) && ((unsigned) (c)) <= 127)
#define ISVARBEG(c) (ISALPHA(c) || c == '_')
-#define ISVARCHR(c) (ISALNUM(c) || c == '_')
+static inline int
+is_name_char (struct wordsplit *wsp, int c)
+{
+ return ISALNUM (c)
+ || c == '_'
+ || ((wsp->ws_options & WRDSO_NAMECHAR)
+ && strchr (wsp->ws_namechar, c));
+}
#define WSP_RETURN_DELIMS(wsp) \
((wsp)->ws_flags & WRDSF_RETURN_DELIMS || ((wsp)->ws_options & WRDSO_MAXWORDS))
@@ -92,6 +99,8 @@ _wsplt_seterr (struct wordsplit *wsp, int ec)
wsp->ws_errno = ec;
if (wsp->ws_flags & WRDSF_SHOWERR)
wordsplit_perror (wsp);
+ if (ec == WRDSE_USAGE)
+ errno = EINVAL;
return ec;
}
@@ -172,8 +181,9 @@ _wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
flags |= wsp->ws_flags & WRDSF_CLOSURE;
}
- wss->ws_options = wsp->ws_options;
-
+ wss->ws_options = wsp->ws_options & ~WRDSO_MAXWORDS;
+ wss->ws_namechar = wsp->ws_namechar;
+
flags |= WRDSF_DELIM
| WRDSF_ALLOC_DIE
| WRDSF_ERROR
@@ -260,11 +270,7 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
if (!(wsp->ws_flags & WRDSF_NOCMD))
{
if (!wsp->ws_command)
- {
- _wsplt_seterr (wsp, WRDSE_USAGE);
- errno = EINVAL;
- return wsp->ws_errno;
- }
+ return _wsplt_seterr (wsp, WRDSE_USAGE);
}
if (wsp->ws_flags & WRDSF_SHOWDBG)
@@ -333,6 +339,14 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
wsp->ws_paramidx = wsp->ws_paramsiz = 0;
wsp->ws_parambuf = NULL;
+ if (wsp->ws_options & WRDSO_NAMECHAR)
+ {
+ if (wsp->ws_namechar[strcspn(wsp->ws_namechar, "${}*@-+?=")])
+ return _wsplt_seterr (wsp, WRDSE_USAGE);
+ }
+ else
+ wsp->ws_namechar = NULL;
+
wsp->ws_endp = 0;
wsp->ws_wordi = 0;
@@ -1387,7 +1401,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
if (ISVARBEG (str[0]))
{
for (i = 1; i < len; i++)
- if (!ISVARCHR (str[i]))
+ if (!is_name_char (wsp, str[i]))
break;
*pend = str + i - 1;
}
@@ -1429,21 +1443,12 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
&& (str[1] == '-'
&& ISDIGIT (str[2]))))) != 0))
{
+ int i0 = str[0] == '-' ? 1 : 0;
str++;
len--;
- for (i = str[0] == '-' ? 1 : 0; i < len; i++)
+ for (i = i0; i < len; i++)
{
- if (str[i] == ':')
- {
- size_t j;
-
- defstr = str + i + 1;
- if (find_closing_paren (str, i + 1, len, &j, "{}"))
- return _wsplt_seterr (wsp, WRDSE_CBRACE);
- *pend = str + j;
- break;
- }
- else if (str[i] == '}')
+ if (str[i] == '}')
{
defstr = NULL;
*pend = str + i;
@@ -1456,6 +1461,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
defstr = str + i;
if (find_closing_paren (str, i, len, &j, "{}"))
return _wsplt_seterr (wsp, WRDSE_CBRACE);
+ if (i > i0 + 1 && str[i-1] == ':')
+ i--;
*pend = str + j;
break;
}
@@ -1473,8 +1480,10 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
return expvar_recover (wsp, str - 1, ptail, pend, flg);
}
}
- else if (!ISVARCHR (str[i]))
+ else if (!is_name_char (wsp, str[i]))
{
+ if (str[i] == ':' && i + 1 < len && strchr ("-+?=", str[i+1]))
+ continue;
return expvar_recover (wsp, str - 1, ptail, pend, flg);
}
}
@@ -1495,54 +1504,46 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
i - its length
defstr - default replacement str */
- if (defstr && strchr("-+?=", defstr[0]) == 0)
+ if (is_param)
{
- rc = WRDSE_UNDEF;
- defstr = NULL;
+ if (param_idx >= 0 && param_idx < wsp->ws_paramc)
+ {
+ value = strdup (wsp->ws_paramv[param_idx]);
+ if (!value)
+ rc = WRDSE_NOSPACE;
+ else
+ rc = WRDSE_OK;
+ }
+ else
+ rc = WRDSE_UNDEF;
}
else
{
- if (is_param)
+ if (wsp->ws_flags & WRDSF_GETVAR)
{
- if (param_idx >= 0 && param_idx < wsp->ws_paramc)
+ if (wsp->ws_options & WRDSO_GETVARPREF)
{
- value = strdup (wsp->ws_paramv[param_idx]);
- if (!value)
- rc = WRDSE_NOSPACE;
- else
- rc = WRDSE_OK;
+ rc = wsplt_env_getvar (wsp, str, i, &value);
+ if (rc == WRDSE_UNDEF)
+ rc = wsplt_env_lookup (wsp, str, i, &value);
}
else
- rc = WRDSE_UNDEF;
- }
- else
- {
- if (wsp->ws_flags & WRDSF_GETVAR)
{
- if (wsp->ws_options & WRDSO_GETVARPREF)
- {
- rc = wsplt_env_getvar (wsp, str, i, &value);
- if (rc == WRDSE_UNDEF)
- rc = wsplt_env_lookup (wsp, str, i, &value);
- }
- else
- {
- rc = wsplt_env_lookup (wsp, str, i, &value);
- if (rc == WRDSE_UNDEF)
- rc = wsplt_env_getvar (wsp, str, i, &value);
- }
+ rc = wsplt_env_lookup (wsp, str, i, &value);
+ if (rc == WRDSE_UNDEF)
+ rc = wsplt_env_getvar (wsp, str, i, &value);
}
- else
- rc = wsplt_env_lookup (wsp, str, i, &value);
}
+ else
+ rc = wsplt_env_lookup (wsp, str, i, &value);
+ }
- if (rc == WRDSE_OK
- && (!value || value[0] == 0)
- && defstr && defstr[-1] == ':')
- {
- free (value);
- rc = WRDSE_UNDEF;
- }
+ if (rc == WRDSE_OK
+ && (!value || value[0] == 0)
+ && defstr && defstr[-1] == ':')
+ {
+ free (value);
+ rc = WRDSE_UNDEF;
}
switch (rc)
@@ -1628,7 +1629,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
else if (wsp->ws_flags & WRDSF_UNDEF)
{
- _wsplt_setctxerr (wsp, WRDSE_UNDEF, str, *pend - str + 1);
+ _wsplt_setctxerr (wsp, WRDSE_UNDEF, str, i);
return 1;
}
else

Return to:

Send suggestions and report system problems to the System administrator.