aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wordsplit.h6
-rw-r--r--src/wordsplit.c42
-rw-r--r--tests/wordsplit.at2
3 files changed, 44 insertions, 6 deletions
diff --git a/include/wordsplit.h b/include/wordsplit.h
index 2fac3c6..0d6eef3 100644
--- a/include/wordsplit.h
+++ b/include/wordsplit.h
@@ -107,20 +107,24 @@ struct wordsplit
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). */
+ char *ws_errctx; /* Context in which the error occurred:
+ For WRDSE_UNDEF - name of the undefined variable,
+ For WRDSE_GLOBERR - pattern that caused error.
+ */
struct wordsplit_node *ws_head, *ws_tail;
/* Doubly-linked list of parsed out nodes. */
char ws_sep[2]; /* Temporary storage used during splitting */
int ws_lvl; /* Invocation nesting level. */
};
diff --git a/src/wordsplit.c b/src/wordsplit.c
index af747b3..6dba914 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -104,12 +104,36 @@ _wsplt_nomem (struct wordsplit *wsp)
if (!(wsp->ws_flags & WRDSF_REUSE))
wordsplit_free (wsp);
wordsplit_free_nodes (wsp);
return wsp->ws_errno;
}
+static void
+_wsplt_store_errctx (struct wordsplit *wsp, char const *str, size_t len)
+{
+ free (wsp->ws_errctx);
+ wsp->ws_errctx = malloc (len + 1);
+ if (!wsp->ws_errctx)
+ {
+ wsp->ws_error ("%s",
+ _("memory exhausted while trying to store error subject"));
+ }
+ else
+ {
+ memcpy (wsp->ws_errctx, str, len);
+ wsp->ws_errctx[len] = 0;
+ }
+}
+
+static inline int
+_wsplt_setctxerr (struct wordsplit *wsp, int ec, char const *str, size_t len)
+{
+ _wsplt_store_errctx (wsp, str, len);
+ return _wsplt_seterr (wsp, ec);
+}
+
static int wordsplit_run (const char *command, size_t length,
struct wordsplit *wsp,
int flags, int lvl);
static int wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
int flags);
@@ -304,12 +328,14 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
wsp->ws_wordi = 0;
if (wsp->ws_flags & WRDSF_REUSE)
wordsplit_free_nodes (wsp);
wsp->ws_head = wsp->ws_tail = NULL;
+ wsp->ws_errctx = NULL;
+
wordsplit_init0 (wsp);
return 0;
}
static int
@@ -1572,13 +1598,13 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
value = NULL;
}
}
else if (wsp->ws_flags & WRDSF_UNDEF)
{
- _wsplt_seterr (wsp, WRDSE_UNDEF);
+ _wsplt_setctxerr (wsp, WRDSE_UNDEF, str, *pend - str + 1);
return 1;
}
else
{
if (wsp->ws_flags & WRDSF_WARNUNDEF)
wsp->ws_error (_("warning: undefined variable `%.*s'"),
@@ -1677,13 +1703,13 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
return 0;
}
static int
begin_var_p (int c)
{
- return memchr("{#@*", c, 4) != NULL || ISVARBEG (c) || ISDIGIT (c);
+ return memchr ("{#@*", c, 4) != NULL || ISVARBEG (c) || ISDIGIT (c);
}
static int
node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
int (*beg_p) (int),
int (*ws_exp_fn) (struct wordsplit *wsp,
@@ -2095,13 +2121,13 @@ wordsplit_pathexpand (struct wordsplit *wsp)
return _wsplt_seterr (wsp, WRDSE_USERERR);
}
continue;
default:
free (pattern);
- return _wsplt_seterr (wsp, WRDSE_GLOBERR);
+ return _wsplt_setctxerr (wsp, WRDSE_GLOBERR, pattern, slen);
}
prev = p;
for (i = 0; i < g.gl_pathc; i++)
{
struct wordsplit_node *newnode;
@@ -2751,18 +2777,23 @@ wordsplit_free_parambuf (struct wordsplit *ws)
void
wordsplit_clearerr (struct wordsplit *ws)
{
if (ws->ws_errno == WRDSE_USERERR)
free (ws->ws_usererr);
ws->ws_usererr = NULL;
+
+ free (ws->ws_errctx);
+ ws->ws_errctx = NULL;
+
ws->ws_errno = WRDSE_OK;
}
void
wordsplit_free (struct wordsplit *ws)
{
+ wordsplit_clearerr (ws);
wordsplit_free_nodes (ws);
wordsplit_free_words (ws);
free (ws->ws_wordv);
ws->ws_wordv = NULL;
wordsplit_free_envbuf (ws);
wordsplit_free_parambuf (ws);
@@ -2820,9 +2851,12 @@ wordsplit_perror (struct wordsplit *wsp)
wsp->ws_error (_("missing closing %c (start near #%lu)"),
wsp->ws_input[wsp->ws_endp],
(unsigned long) wsp->ws_endp);
break;
default:
- wsp->ws_error ("%s", wordsplit_strerror (wsp));
+ if (wsp->ws_errctx)
+ wsp->ws_error ("%s: %s", wordsplit_strerror (wsp), wsp->ws_errctx);
+ else
+ wsp->ws_error ("%s", wordsplit_strerror (wsp));
}
}
diff --git a/tests/wordsplit.at b/tests/wordsplit.at
index 0a7d7db..7ecc016 100644
--- a/tests/wordsplit.at
+++ b/tests/wordsplit.at
@@ -235,13 +235,13 @@ TOTAL: 0
],
[unset FOO;])
TESTWSP([bail out on undefined variables],[],[-undef],
[$FOO],
[],
-[undefined variable
+[undefined variable: FOO
],
[unset FOO;])
TESTWSP([disable variable expansion],[],[-novar],
[$FOO],
[NF: 1

Return to:

Send suggestions and report system problems to the System administrator.