aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-05-14 19:59:07 +0300
committerSergey Poznyakoff <gray@gnu.org>2019-05-14 19:59:07 +0300
commit39beda10e855d265b5af74ea53a5d7a89a91296a (patch)
tree86f671ebea706d691d1667304522c260f56924bd
parentf6586d810d8430d6d9f833119af39726a60e4a6c (diff)
downloadgrecs-39beda10e855d265b5af74ea53a5d7a89a91296a.tar.gz
grecs-39beda10e855d265b5af74ea53a5d7a89a91296a.tar.bz2
wordsplit: whitespace cleanup
-rw-r--r--include/wordsplit.h38
-rw-r--r--src/wordsplit.c147
2 files changed, 92 insertions, 93 deletions
diff --git a/include/wordsplit.h b/include/wordsplit.h
index d7eb26f..d4975b3 100644
--- a/include/wordsplit.h
+++ b/include/wordsplit.h
@@ -21,114 +21,114 @@
typedef struct wordsplit wordsplit_t;
/* Structure used to direct the splitting. Members marked with [Input]
can be defined before calling wordsplit(), those marked with [Output]
provide return values when the function returns. If neither mark is
used, the member is internal and must not be used by the caller.
In the comments below, the identifiers in parentheses indicate bits that
must be set (or unset, if starting with !) in ws_flags (if starting with
WRDSF_) or ws_options (if starting with WRDSO_) to initialize or use the
given member.
-
+
If not redefined explicitly, most of them are set to some reasonable
default value upon entry to wordsplit(). */
-struct wordsplit
+struct wordsplit
{
size_t ws_wordc; /* [Output] Number of words in ws_wordv. */
char **ws_wordv; /* [Output] Array of parsed out words. */
size_t ws_offs; /* [Input] (WRDSF_DOOFFS) Number of initial
elements in ws_wordv to fill with NULLs. */
- size_t ws_wordn; /* Number of elements ws_wordv can accomodate. */
+ size_t ws_wordn; /* Number of elements ws_wordv can accomodate. */
int ws_flags; /* [Input] Flags passed to wordsplit. */
int ws_options; /* [Input] (WRDSF_OPTIONS)
Additional options. */
size_t ws_maxwords; /* [Input] (WRDSO_MAXWORDS) Return at most that
many words */
size_t ws_wordi; /* [Output] (WRDSF_INCREMENTAL) Total number of
words returned so far */
const char *ws_delim; /* [Input] (WRDSF_DELIM) Word delimiters. */
const char *ws_comment; /* [Input] (WRDSF_COMMENT) Comment characters. */
const char *ws_escape[2]; /* [Input] (WRDSF_ESCAPE) Characters to be escaped
with backslash. */
void (*ws_alloc_die) (wordsplit_t *wsp);
- /* [Input] (WRDSF_ALLOC_DIE) Function called when
+ /* [Input] (WRDSF_ALLOC_DIE) Function called when
out of memory. Must not return. */
void (*ws_error) (const char *, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
- /* [Input] (WRDSF_ERROR) Function used for error
+ __attribute__ ((__format__ (__printf__, 1, 2)));
+ /* [Input] (WRDSF_ERROR) Function used for error
reporting */
void (*ws_debug) (const char *, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
- /* [Input] (WRDSF_DEBUG) Function used for debug
+ __attribute__ ((__format__ (__printf__, 1, 2)));
+ /* [Input] (WRDSF_DEBUG) Function used for debug
output. */
const char **ws_env; /* [Input] (WRDSF_ENV, !WRDSF_NOVAR) Array of
environment variables. */
/* Temporary storage for environment variables. It is initialized
upon first assignment which occurs during the parsing process
(e.g. ${x:=2}). When this happens, all variables from ws_env are
moved to ws_envbuf first, and the ws_envbuf address is assigned
to ws_env. From this moment on, all variable expansions are served
from ws_envbuf. */
char **ws_envbuf; /* Storage for variables */
size_t ws_envidx; /* Index of first free slot */
size_t ws_envsiz; /* Size of the ws_envbuf array */
char const **ws_paramv; /* [WRDSO_PARAMV] User-supplied positional
parameters */
size_t ws_paramc; /* Number of positional parameters */
- /* Temporary storage for parameters. Works similarly to ws_enbuf.
+ /* Temporary storage for parameters. Works similarly to ws_enbuf.
*/
char **ws_parambuf;
size_t ws_paramidx;
size_t ws_paramsiz;
-
+
int (*ws_getvar) (char **ret, const char *var, size_t len, void *clos);
- /* [Input] (WRDSF_GETVAR, !WRDSF_NOVAR) Looks up
+ /* [Input] (WRDSF_GETVAR, !WRDSF_NOVAR) Looks up
the name VAR (LEN bytes long) in the table of
variables and if found returns in memory
location pointed to by RET the value of that
variable. Returns WRDSE_OK (0) on success,
and an error code (see WRDSE_* defines below)
on error. User-specific errors can be returned
by storing the error diagnostic string in RET
and returning WRDSE_USERERR.
- Whatever is stored in RET, it must be allocated
+ Whatever is stored in RET, it must be allocated
using malloc(3). */
void *ws_closure; /* [Input] (WRDSF_CLOSURE) Passed as the CLOS
argument to ws_getvar and ws_command. */
int (*ws_command) (char **ret, const char *cmd, size_t len, char **argv,
- void *clos);
- /* [Input] (!WRDSF_NOCMD) Returns in the memory
+ void *clos);
+ /* [Input] (!WRDSF_NOCMD) Returns in the memory
location pointed to by RET the expansion of
the command CMD (LEN bytes long). On input,
ARGV contains CMD split out to words.
See ws_getvar for a discussion of possible
return values. */
- const char *ws_input; /* Input string (the S argument to wordsplit. */
+ const char *ws_input; /* Input string (the S argument to wordsplit. */
size_t ws_len; /* Length of ws_input. */
size_t ws_endp; /* Points past the last processed byte in
ws_input. */
int ws_errno; /* [Output] Error code, if an error occurred. */
char *ws_usererr; /* Points to textual description of
the error, if ws_errno is WRDSE_USERERR. Must
be allocated with malloc(3). */
struct wordsplit_node *ws_head, *ws_tail;
- /* Doubly-linked list of parsed out nodes. */
+ /* Doubly-linked list of parsed out nodes. */
int ws_lvl; /* Invocation nesting level. */
};
/* Initial size for ws_env, if allocated automatically */
#define WORDSPLIT_ENV_INIT 16
/* Wordsplit flags. */
/* Append the words found to the array resulting from a previous
call. */
#define WRDSF_APPEND 0x00000001
/* Insert ws_offs initial NULLs in the array ws_wordv.
(These are not counted in the returned ws_wordc.) */
@@ -233,27 +233,27 @@ struct wordsplit
(e.g. ${VAR:-foo bar}) */
#define WRDSO_NOVARSPLIT 0x00001000
/* Don't split commands, even containing whitespace, e.g.
$(echo foo bar) */
#define WRDSO_NOCMDSPLIT 0x00002000
/* Enable positional parameters */
#define WRDSO_PARAMV 0x00004000
/* Enable negative positional indices (${-1} is the last positional
parameter) */
#define WRDSO_PARAM_NEGIDX 0x00008000
-#define WRDSO_BSKEEP WRDSO_BSKEEP_WORD
-#define WRDSO_OESC WRDSO_OESC_WORD
-#define WRDSO_XESC WRDSO_XESC_WORD
+#define WRDSO_BSKEEP WRDSO_BSKEEP_WORD
+#define WRDSO_OESC WRDSO_OESC_WORD
+#define WRDSO_XESC WRDSO_XESC_WORD
/* Indices into ws_escape */
#define WRDSX_WORD 0
#define WRDSX_QUOTE 1
/* Set escape option F in WS for words (Q==0) or quoted strings (Q==1) */
#define WRDSO_ESC_SET(ws,q,f) ((ws)->ws_options |= ((f) << 4*(q)))
/* Test WS for escape option F for words (Q==0) or quoted strings (Q==1) */
#define WRDSO_ESC_TEST(ws,q,f) ((ws)->ws_options & ((f) << 4*(q)))
#define WRDSE_OK 0
#define WRDSE_EOF WRDSE_OK
diff --git a/src/wordsplit.c b/src/wordsplit.c
index 05c3643..f563725 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -61,46 +61,46 @@
(ISDIGIT(c) ? c - '0' : (ISXDIGIT(c) ? toupper(c) - 'A' + 10 : 255 ))
#define ALLOC_INIT 128
#define ALLOC_INCR 128
static void
_wsplt_alloc_die (struct wordsplit *wsp)
{
wsp->ws_error ("%s", _("memory exhausted"));
abort ();
}
-static void
+static void
_wsplt_error (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
va_end (ap);
fputc ('\n', stderr);
}
static void wordsplit_free_nodes (struct wordsplit *);
static int
_wsplt_seterr (struct wordsplit *wsp, int ec)
{
wsp->ws_errno = ec;
if (wsp->ws_flags & WRDSF_SHOWERR)
wordsplit_perror (wsp);
return ec;
}
-
+
static int
_wsplt_nomem (struct wordsplit *wsp)
{
errno = ENOMEM;
wsp->ws_errno = WRDSE_NOSPACE;
if (wsp->ws_flags & WRDSF_ENOMEMABRT)
wsp->ws_alloc_die (wsp);
if (wsp->ws_flags & WRDSF_SHOWERR)
wordsplit_perror (wsp);
if (!(wsp->ws_flags & WRDSF_REUSE))
wordsplit_free (wsp);
wordsplit_free_nodes (wsp);
@@ -113,54 +113,54 @@ static int wordsplit_run (const char *command, size_t length,
static int wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
int flags);
static int wordsplit_process_list (struct wordsplit *wsp, size_t start);
static int wordsplit_finish (struct wordsplit *wsp);
static int
_wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
char const *str, int len,
int flags, int finalize)
{
int rc;
-
+
wss->ws_delim = wsp->ws_delim;
wss->ws_debug = wsp->ws_debug;
wss->ws_error = wsp->ws_error;
wss->ws_alloc_die = wsp->ws_alloc_die;
if (!(flags & WRDSF_NOVAR))
{
wss->ws_env = wsp->ws_env;
wss->ws_getvar = wsp->ws_getvar;
flags |= wsp->ws_flags & (WRDSF_ENV | WRDSF_ENV_KV | WRDSF_GETVAR);
}
if (!(flags & WRDSF_NOCMD))
{
wss->ws_command = wsp->ws_command;
}
if ((flags & (WRDSF_NOVAR|WRDSF_NOCMD)) != (WRDSF_NOVAR|WRDSF_NOCMD))
{
wss->ws_closure = wsp->ws_closure;
flags |= wsp->ws_flags & WRDSF_CLOSURE;
}
wss->ws_options = wsp->ws_options;
-
+
flags |= WRDSF_DELIM
- | WRDSF_ALLOC_DIE
- | WRDSF_ERROR
- | WRDSF_DEBUG
- | (wsp->ws_flags & (WRDSF_SHOWDBG | WRDSF_SHOWERR | WRDSF_OPTIONS));
+ | WRDSF_ALLOC_DIE
+ | WRDSF_ERROR
+ | WRDSF_DEBUG
+ | (wsp->ws_flags & (WRDSF_SHOWDBG | WRDSF_SHOWERR | WRDSF_OPTIONS));
rc = wordsplit_init (wss, str, len, flags);
if (rc)
return rc;
wss->ws_lvl = wsp->ws_lvl + 1;
rc = wordsplit_process_list (wss, 0);
if (rc)
{
wordsplit_free_nodes (wss);
return rc;
}
if (finalize)
@@ -196,25 +196,25 @@ wordsplit_init0 (struct wordsplit *wsp)
}
else
{
wsp->ws_wordv = NULL;
wsp->ws_wordc = 0;
wsp->ws_wordn = 0;
}
wsp->ws_errno = 0;
}
char wordsplit_c_escape_tab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
-
+
static int
wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
int flags)
{
wsp->ws_flags = flags;
if (!(wsp->ws_flags & WRDSF_ALLOC_DIE))
wsp->ws_alloc_die = _wsplt_alloc_die;
if (!(wsp->ws_flags & WRDSF_ERROR))
wsp->ws_error = _wsplt_error;
if (!(wsp->ws_flags & WRDSF_NOVAR))
@@ -269,52 +269,52 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
{
if (!wsp->ws_escape[WRDSX_WORD])
wsp->ws_escape[WRDSX_WORD] = "";
if (!wsp->ws_escape[WRDSX_QUOTE])
wsp->ws_escape[WRDSX_QUOTE] = "";
}
else
{
if (wsp->ws_flags & WRDSF_CESCAPES)
{
wsp->ws_escape[WRDSX_WORD] = wordsplit_c_escape_tab;
wsp->ws_escape[WRDSX_QUOTE] = wordsplit_c_escape_tab;
- wsp->ws_options |= WRDSO_OESC_QUOTE | WRDSO_OESC_WORD
- | WRDSO_XESC_QUOTE | WRDSO_XESC_WORD;
+ wsp->ws_options |= WRDSO_OESC_QUOTE | WRDSO_OESC_WORD
+ | WRDSO_XESC_QUOTE | WRDSO_XESC_WORD;
}
else
{
wsp->ws_escape[WRDSX_WORD] = "";
wsp->ws_escape[WRDSX_QUOTE] = "\\\\\"\"";
wsp->ws_options |= WRDSO_BSKEEP_QUOTE;
}
}
if (!(wsp->ws_options & WRDSO_PARAMV))
{
wsp->ws_paramv = NULL;
wsp->ws_paramc = 0;
}
wsp->ws_paramidx = wsp->ws_paramsiz = 0;
wsp->ws_parambuf = NULL;
-
+
wsp->ws_endp = 0;
wsp->ws_wordi = 0;
if (wsp->ws_flags & WRDSF_REUSE)
wordsplit_free_nodes (wsp);
wsp->ws_head = wsp->ws_tail = NULL;
-
+
wordsplit_init0 (wsp);
-
+
return 0;
}
static int
alloc_space (struct wordsplit *wsp, size_t count)
{
size_t offs = (wsp->ws_flags & WRDSF_DOOFFS) ? wsp->ws_offs : 0;
char **ptr;
size_t newalloc;
if (wsp->ws_wordv == NULL)
{
@@ -582,25 +582,25 @@ wordsplit_dump_nodes (struct wordsplit *wsp)
}
static int
coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
{
struct wordsplit_node *p, *end;
size_t len = 0;
char *buf, *cur;
int stop;
if (!(node->flags & _WSNF_JOIN))
return 0;
-
+
for (p = node; p && (p->flags & _WSNF_JOIN); p = p->next)
{
len += wsnode_len (p);
}
if (p)
len += wsnode_len (p);
end = p;
buf = malloc (len + 1);
if (!buf)
return _wsplt_nomem (wsp);
cur = buf;
@@ -712,42 +712,42 @@ static size_t skip_delim (struct wordsplit *wsp);
static int
wordsplit_finish (struct wordsplit *wsp)
{
struct wordsplit_node *p;
size_t n;
int delim;
/* Postprocess delimiters. It would be rather simple, if it weren't for
the incremental operation.
Nodes of type _WSNF_DELIM get inserted to the node list if either
WRDSF_RETURN_DELIMS flag or WRDSO_MAXWORDS option is set.
-
+
The following cases should be distinguished:
1. If both WRDSF_SQUEEZE_DELIMS and WRDSF_RETURN_DELIMS are set, compress
- any runs of similar delimiter nodes to a single node. The nodes are
+ any runs of similar delimiter nodes to a single node. The nodes are
'similar' if they point to the same delimiter character.
If WRDSO_MAXWORDS option is set, stop compressing when
ws_wordi + 1 == ws_maxwords, and coalesce the rest of nodes into
a single last node.
2. If WRDSO_MAXWORDS option is set, but WRDSF_RETURN_DELIMS is not,
- remove any delimiter nodes. Stop operation when
+ remove any delimiter nodes. Stop operation when
ws_wordi + 1 == ws_maxwords, and coalesce the rest of nodes into
a single last node.
3. If incremental operation is in progress, restart the loop any time
- a delimiter node is about to be returned, unless WRDSF_RETURN_DELIMS
+ a delimiter node is about to be returned, unless WRDSF_RETURN_DELIMS
is set.
*/
again:
delim = 0; /* Delimiter being processed (if any) */
n = 0; /* Number of words processed so far */
p = wsp->ws_head; /* Current node */
while (p)
{
struct wordsplit_node *next = p->next;
if (p->flags & _WSNF_DELIM)
{
@@ -776,25 +776,25 @@ wordsplit_finish (struct wordsplit *wsp)
p = next;
continue;
}
}
}
else if (wsp->ws_options & WRDSO_MAXWORDS)
{
wsnode_remove (wsp, p);
p = next;
continue;
}
}
- else
+ else
{
if (delim)
{
/* Last node was a delimiter or a compressed run of delimiters;
Count it, and clear the delimiter marker */
n++;
delim = 0;
}
if (wsp->ws_options & WRDSO_MAXWORDS)
{
if (wsp->ws_wordi + n + 1 == wsp->ws_maxwords)
break;
@@ -849,26 +849,26 @@ wordsplit_finish (struct wordsplit *wsp)
}
if (alloc_space (wsp, n + 1))
return wsp->ws_errno;
while (wsp->ws_head)
{
const char *str = wsnode_ptr (wsp, wsp->ws_head);
size_t slen = wsnode_len (wsp->ws_head);
char *newstr = malloc (slen + 1);
/* Assign newstr first, even if it is NULL. This way
- wordsplit_free will work even if we return
- nomem later. */
+ wordsplit_free will work even if we return
+ nomem later. */
wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = newstr;
if (!newstr)
return _wsplt_nomem (wsp);
memcpy (newstr, str, slen);
newstr[slen] = 0;
wsnode_remove (wsp, wsp->ws_head);
wsp->ws_wordc++;
wsp->ws_wordi++;
if (wsp->ws_flags & WRDSF_INCREMENTAL)
@@ -963,25 +963,25 @@ find_closing_paren (const char *str, size_t i, size_t len, size_t *poff,
break;
}
else if (str[i] == paren[1])
{
if (--level == 0)
{
*poff = i;
return 0;
}
break;
}
break;
-
+
case '"':
state = st_dquote;
break;
case '\'':
state = st_squote;
break;
}
break;
case st_squote:
if (str[i] == '\'')
@@ -1043,94 +1043,94 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len,
}
}
}
return WRDSE_UNDEF;
}
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;
-
+
if (wsp->ws_envidx + n >= wsp->ws_envsiz)
{
size_t sz;
char **newenv;
if (!wsp->ws_envbuf)
{
if (wsp->ws_flags & WRDSF_ENV)
{
size_t i = 0, j;
if (wsp->ws_env)
{
for (; wsp->ws_env[i]; i++)
;
}
-
+
sz = i + n + 1;
newenv = calloc (sz, sizeof(newenv[0]));
if (!newenv)
return _wsplt_nomem (wsp);
for (j = 0; j < i; j++)
{
newenv[j] = strdup (wsp->ws_env[j]);
if (!newenv[j])
{
for (; j > 1; j--)
free (newenv[j-1]);
free (newenv);
return _wsplt_nomem (wsp);
}
}
newenv[j] = NULL;
-
+
wsp->ws_envbuf = newenv;
wsp->ws_envidx = i;
wsp->ws_envsiz = sz;
wsp->ws_env = (const char**) wsp->ws_envbuf;
}
else
{
newenv = calloc (WORDSPLIT_ENV_INIT, sizeof(newenv[0]));
if (!newenv)
return _wsplt_nomem (wsp);
wsp->ws_envbuf = newenv;
wsp->ws_envidx = 0;
wsp->ws_envsiz = WORDSPLIT_ENV_INIT;
wsp->ws_env = (const char**) wsp->ws_envbuf;
wsp->ws_flags |= WRDSF_ENV;
}
}
else
{
size_t n = wsp->ws_envsiz;
-
+
if ((size_t) -1 / 3 * 2 / sizeof (wsp->ws_envbuf[0]) <= n)
return _wsplt_nomem (wsp);
n += (n + 1) / 2;
newenv = realloc (wsp->ws_envbuf, n * sizeof (wsp->ws_envbuf[0]));
if (!newenv)
return _wsplt_nomem (wsp);
wsp->ws_envbuf = newenv;
wsp->ws_envsiz = n;
wsp->ws_env = (const char**) wsp->ws_envbuf;
}
}
-
+
if (wsp->ws_flags & WRDSF_ENV_KV)
{
/* A key-value pair environment */
char *p = malloc (namelen + 1);
if (!p)
return _wsplt_nomem (wsp);
memcpy (p, name, namelen);
p[namelen] = 0;
v = strdup (value);
if (!v)
{
@@ -1149,79 +1149,79 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
v[namelen++] = '=';
strcpy(v + namelen, value);
wsp->ws_env[wsp->ws_envidx++] = v;
}
wsp->ws_env[wsp->ws_envidx++] = NULL;
return WRDSE_OK;
}
int
wsplt_assign_param (struct wordsplit *wsp, int param_idx, char *value)
{
char *v;
-
+
if (param_idx < 0)
return WRDSE_BADPARAM;
if (param_idx == wsp->ws_paramc)
{
char **parambuf;
if (!wsp->ws_parambuf)
{
size_t i;
-
+
parambuf = calloc ((size_t)param_idx + 1, sizeof (parambuf[0]));
if (!parambuf)
return _wsplt_nomem (wsp);
for (i = 0; i < wsp->ws_paramc; i++)
{
parambuf[i] = strdup (wsp->ws_paramv[i]);
if (!parambuf[i])
{
for (; i > 1; i--)
free (parambuf[i-1]);
free (parambuf);
return _wsplt_nomem (wsp);
}
}
-
+
wsp->ws_parambuf = parambuf;
wsp->ws_paramidx = param_idx;
wsp->ws_paramsiz = param_idx + 1;
}
else
{
size_t n = wsp->ws_paramsiz;
-
+
if ((size_t) -1 / 3 * 2 / sizeof (wsp->ws_parambuf[0]) <= n)
return _wsplt_nomem (wsp);
n += (n + 1) / 2;
parambuf = realloc (wsp->ws_parambuf, n * sizeof (wsp->ws_parambuf[0]));
if (!parambuf)
return _wsplt_nomem (wsp);
wsp->ws_parambuf = parambuf;
wsp->ws_paramsiz = n;
wsp->ws_parambuf[param_idx] = NULL;
}
wsp->ws_paramv = (const char**) wsp->ws_parambuf;
wsp->ws_paramc = param_idx + 1;
}
else if (param_idx > wsp->ws_paramc)
return WRDSE_BADPARAM;
-
+
v = strdup (value);
if (!v)
return _wsplt_nomem (wsp);
-
+
free (wsp->ws_parambuf[param_idx]);
wsp->ws_parambuf[param_idx] = v;
return WRDSE_OK;
}
/* Recover from what looked like a variable reference, but turned out
not to be one. STR points to first character after '$'. */
static int
expvar_recover (struct wordsplit *wsp, const char *str,
struct wordsplit_node **ptail, const char **pend, int flg)
{
struct wordsplit_node *newnode;
@@ -1238,83 +1238,83 @@ expvar_recover (struct wordsplit *wsp, const char *str,
newnode->v.word[1] = str[0];
newnode->v.word[2] = 0;
*pend = str;
return 0;
}
static int
expand_paramv (struct wordsplit *wsp, struct wordsplit_node **ptail, int flg,
int q)
{
struct wordsplit ws;
int wsflags = WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE
- | (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0)
- | (q ? WRDSF_NOSPLIT : 0);
+ | (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0)
+ | (q ? WRDSF_NOSPLIT : 0);
size_t i;
-
+
for (i = 0; i < wsp->ws_paramc; i++)
{
struct wordsplit_node *np;
int rc = _wsplt_subsplit (wsp, &ws,
wsp->ws_paramv[i], strlen (wsp->ws_paramv[i]),
wsflags, q);
if (rc)
{
_wsplt_seterr_sub (wsp, &ws);
wordsplit_free (&ws);
return 1;
}
if (q)
{
if (wsnode_new (wsp, &np))
return 1;
wsnode_insert (wsp, np, *ptail, 0);
*ptail = np;
np->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
np->v.word = ws.ws_wordv[0];
-
+
ws.ws_wordv[0] = NULL;
}
else
{
for (np = ws.ws_head; np; np = np->next)
np->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
wsnode_insert (wsp, ws.ws_head, *ptail, 0);
*ptail = ws.ws_tail;
ws.ws_head = ws.ws_tail = NULL;
}
-
+
wsflags |= WRDSF_REUSE;
}
if (wsflags & WRDSF_REUSE)
wordsplit_free (&ws);
return 0;
}
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;
-
+
if (ISVARBEG (str[0]))
{
for (i = 1; i < len; i++)
if (!ISVARCHR (str[i]))
break;
*pend = str + i - 1;
}
else if ((wsp->ws_options & WRDSO_PARAMV) && ISDIGIT (str[0]))
{
i = 1;
*pend = str;
is_param = 1;
@@ -1349,41 +1349,41 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
&& ISDIGIT (str[1]))
|| ((wsp->ws_options & WRDSO_PARAM_NEGIDX)
&& (str[1] == '-'
&& ISDIGIT (str[2]))))) != 0))
{
str++;
len--;
for (i = str[0] == '-' ? 1 : 0; 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] == '}')
{
defstr = NULL;
*pend = str + i;
break;
}
else if (strchr ("-+?=", str[i]))
{
size_t j;
-
+
defstr = str + i;
if (find_closing_paren (str, i, len, &j, "{}"))
return _wsplt_seterr (wsp, WRDSE_CBRACE);
*pend = str + j;
break;
}
else if (is_param)
{
if (ISDIGIT (str[i]))
{
param_idx = param_idx * 10 + to_num (str[i]);
if ((str[0] == '-' && -param_idx < INT_MIN)
@@ -1391,28 +1391,28 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
return expvar_recover (wsp, str - 1, ptail, pend, flg);
}
else
{
return expvar_recover (wsp, str - 1, ptail, pend, flg);
}
}
else if (!ISVARCHR (str[i]))
{
return expvar_recover (wsp, str - 1, ptail, pend, flg);
}
}
-
+
if (is_param && str[0] == '-')
param_idx = wsp->ws_paramc - param_idx;
-
+
if (i == len)
return _wsplt_seterr (wsp, WRDSE_CBRACE);
}
else
{
return expvar_recover (wsp, str, ptail, pend, flg);
}
/* Actually expand the variable */
/* str - start of the variable name
i - its length
defstr - default replacement str */
@@ -1447,88 +1447,88 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
value = strdup (vptr);
if (!value)
rc = WRDSE_NOSPACE;
}
else
rc = WRDSE_UNDEF;
}
else if (wsp->ws_flags & WRDSF_GETVAR)
rc = wsp->ws_getvar (&value, str, i, wsp->ws_closure);
else
rc = WRDSE_UNDEF;
}
-
+
if (rc == WRDSE_OK
&& (!value || value[0] == 0)
&& defstr && defstr[-1] == ':')
{
free (value);
rc = WRDSE_UNDEF;
}
}
-
+
switch (rc)
{
case WRDSE_OK:
if (defstr && *defstr == '+')
{
size_t size = *pend - ++defstr;
rc = _wsplt_subsplit (wsp, &ws, defstr, size,
WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
(wsp->ws_flags &
(WRDSF_NOVAR | WRDSF_NOCMD)), 1);
if (rc)
return rc;
free (value);
value = ws.ws_wordv[0];
ws.ws_wordv[0] = NULL;
wordsplit_free (&ws);
}
break;
-
+
case WRDSE_UNDEF:
if (defstr)
{
size_t size;
if (*defstr == '-' || *defstr == '=')
{
size = *pend - ++defstr;
rc = _wsplt_subsplit (wsp, &ws, defstr, size,
WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
(wsp->ws_flags &
(WRDSF_NOVAR | WRDSF_NOCMD)),
1);
if (rc)
return rc;
value = ws.ws_wordv[0];
ws.ws_wordv[0] = NULL;
wordsplit_free (&ws);
-
+
if (defstr[-1] == '=')
{
if (is_param)
rc = wsplt_assign_param (wsp, param_idx, value);
else
rc = wsplt_assign_var (wsp, str, i, value);
}
if (rc)
{
free (value);
return rc;
}
}
- else
+ else
{
if (*defstr == '?')
{
size = *pend - ++defstr;
if (size == 0)
wsp->ws_error (_("%.*s: variable null or not set"),
(int) i, str);
else
{
rc = _wsplt_subsplit (wsp, &ws, defstr, size,
WRDSF_NOSPLIT | WRDSF_WS |
WRDSF_QUOTE |
@@ -1558,25 +1558,25 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
wsp->ws_error (_("warning: undefined variable `%.*s'"),
(int) i, str);
if (wsp->ws_flags & WRDSF_KEEPUNDEF)
value = NULL;
else
{
value = strdup ("");
if (!value)
return _wsplt_nomem (wsp);
}
}
break;
-
+
case WRDSE_NOSPACE:
return _wsplt_nomem (wsp);
case WRDSE_USERERR:
if (wsp->ws_errno == WRDSE_USERERR)
free (wsp->ws_usererr);
wsp->ws_usererr = value;
/* fall through */
default:
_wsplt_seterr (wsp, rc);
return 1;
}
@@ -1597,25 +1597,25 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
free (value);
/* Empty string is a special case */
if (wsnode_new (wsp, &newnode))
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
*ptail = newnode;
newnode->flags = _WSNF_NULL;
}
else
{
struct wordsplit ws;
int rc;
-
+
rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
WRDSF_NOVAR | WRDSF_NOCMD |
WRDSF_QUOTE
| (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0) ,
0);
free (value);
if (rc)
{
_wsplt_seterr_sub (wsp, &ws);
wordsplit_free (&ws);
return 1;
}
@@ -1702,25 +1702,25 @@ node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
tail->flags |= _WSNF_JOIN;
if (node_split_prefix (wsp, &tail, node, off, p - str,
node->flags & (_WSNF_JOIN|_WSNF_QUOTE)))
return 1;
}
if (tail != node)
{
wsnode_remove (wsp, node);
wsnode_free (node);
}
return 0;
}
-
+
/* Remove NULL nodes from the list */
static void
wsnode_nullelim (struct wordsplit *wsp)
{
struct wordsplit_node *p;
for (p = wsp->ws_head; p;)
{
struct wordsplit_node *next = p->next;
if (p->flags & _WSNF_DELIM && p->prev)
p->prev->flags &= ~_WSNF_JOIN;
if (p->flags & _WSNF_NULL)
@@ -1756,45 +1756,45 @@ begin_cmd_p (int c)
return c == '(';
}
static int
expcmd (struct wordsplit *wsp, const char *str, size_t len,
struct wordsplit_node **ptail, const char **pend, int flg)
{
int rc;
size_t j;
char *value;
struct wordsplit_node *newnode;
struct wordsplit ws;
-
+
str++;
len--;
if (find_closing_paren (str, 0, len, &j, "()"))
{
_wsplt_seterr (wsp, WRDSE_PAREN);
return 1;
}
*pend = str + j;
rc = _wsplt_subsplit (wsp, &ws, str, j, WRDSF_WS | WRDSF_QUOTE, 1);
if (rc)
{
_wsplt_seterr_sub (wsp, &ws);
wordsplit_free (&ws);
return 1;
}
rc = wsp->ws_command (&value, str, j, ws.ws_wordv, wsp->ws_closure);
wordsplit_free (&ws);
-
+
if (rc == WRDSE_NOSPACE)
return _wsplt_nomem (wsp);
else if (rc)
{
if (rc == WRDSE_USERERR)
{
if (wsp->ws_errno == WRDSE_USERERR)
free (wsp->ws_usererr);
wsp->ws_usererr = value;
}
_wsplt_seterr (wsp, rc);
return 1;
@@ -1884,65 +1884,65 @@ wordsplit_trimws (struct wordsplit *wsp)
for (p = wsp->ws_head; p; p = p->next)
{
size_t n;
if (!(p->flags & _WSNF_QUOTE))
{
/* Skip leading whitespace: */
for (n = p->v.segm.beg; n < p->v.segm.end && ISWS (wsp->ws_input[n]);
n++)
;
p->v.segm.beg = n;
}
-
+
while (p->next && (p->flags & _WSNF_JOIN))
p = p->next;
-
+
if (p->flags & _WSNF_QUOTE)
continue;
-
+
/* Trim trailing whitespace */
for (n = p->v.segm.end;
n > p->v.segm.beg && ISWS (wsp->ws_input[n - 1]); n--);
p->v.segm.end = n;
if (p->v.segm.beg == p->v.segm.end)
p->flags |= _WSNF_NULL;
}
wsnode_nullelim (wsp);
return 0;
}
static int
wordsplit_tildexpand (struct wordsplit *wsp)
{
struct wordsplit_node *p;
char *uname = NULL;
size_t usize = 0;
-
+
for (p = wsp->ws_head; p; p = p->next)
{
const char *str;
if (p->flags & _WSNF_QUOTE)
continue;
str = wsnode_ptr (wsp, p);
if (str[0] == '~')
{
size_t i, size, dlen;
size_t slen = wsnode_len (p);
struct passwd *pw;
char *newstr;
-
+
for (i = 1; i < slen && str[i] != '/'; i++)
;
if (i == slen)
continue;
if (i > 1)
{
if (i > usize)
{
char *p = realloc (uname, i);
if (!p)
{
free (uname);
@@ -2000,96 +2000,96 @@ static int
wordsplit_pathexpand (struct wordsplit *wsp)
{
struct wordsplit_node *p, *next;
char *pattern = NULL;
size_t patsize = 0;
size_t slen;
int flags = 0;
#ifdef GLOB_PERIOD
if (wsp->ws_options & WRDSO_DOTGLOB)
<