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
@@ -110,7 +110,7 @@ struct wordsplit
110 See ws_getvar for a discussion of possible 110 See ws_getvar for a discussion of possible
111 return values. */ 111 return values. */
112 112
113 const char *ws_input; /* Input string (the S argument to wordsplit. */ 113 const char *ws_input; /* Input string (the S argument to wordsplit). */
114 size_t ws_len; /* Length of ws_input. */ 114 size_t ws_len; /* Length of ws_input. */
115 size_t ws_endp; /* Points past the last processed byte in 115 size_t ws_endp; /* Points past the last processed byte in
116 ws_input. */ 116 ws_input. */
@@ -118,6 +118,10 @@ struct wordsplit
118 char *ws_usererr; /* Points to textual description of 118 char *ws_usererr; /* Points to textual description of
119 the error, if ws_errno is WRDSE_USERERR. Must 119 the error, if ws_errno is WRDSE_USERERR. Must
120 be allocated with malloc(3). */ 120 be allocated with malloc(3). */
121 char *ws_errctx; /* Context in which the error occurred:
122 For WRDSE_UNDEF - name of the undefined variable,
123 For WRDSE_GLOBERR - pattern that caused error.
124 */
121 struct wordsplit_node *ws_head, *ws_tail; 125 struct wordsplit_node *ws_head, *ws_tail;
122 /* Doubly-linked list of parsed out nodes. */ 126 /* Doubly-linked list of parsed out nodes. */
123 char ws_sep[2]; /* Temporary storage used during splitting */ 127 char ws_sep[2]; /* Temporary storage used during splitting */
diff --git a/src/wordsplit.c b/src/wordsplit.c
index af747b3..6dba914 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -107,6 +107,30 @@ _wsplt_nomem (struct wordsplit *wsp)
107 return wsp->ws_errno; 107 return wsp->ws_errno;
108} 108}
109 109
110static void
111_wsplt_store_errctx (struct wordsplit *wsp, char const *str, size_t len)
112{
113 free (wsp->ws_errctx);
114 wsp->ws_errctx = malloc (len + 1);
115 if (!wsp->ws_errctx)
116 {
117 wsp->ws_error ("%s",
118 _("memory exhausted while trying to store error subject"));
119 }
120 else
121 {
122 memcpy (wsp->ws_errctx, str, len);
123 wsp->ws_errctx[len] = 0;
124 }
125}
126
127static inline int
128_wsplt_setctxerr (struct wordsplit *wsp, int ec, char const *str, size_t len)
129{
130 _wsplt_store_errctx (wsp, str, len);
131 return _wsplt_seterr (wsp, ec);
132}
133
110static int wordsplit_run (const char *command, size_t length, 134static int wordsplit_run (const char *command, size_t length,
111 struct wordsplit *wsp, 135 struct wordsplit *wsp,
112 int flags, int lvl); 136 int flags, int lvl);
@@ -307,6 +331,8 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
307 wordsplit_free_nodes (wsp); 331 wordsplit_free_nodes (wsp);
308 wsp->ws_head = wsp->ws_tail = NULL; 332 wsp->ws_head = wsp->ws_tail = NULL;
309 333
334 wsp->ws_errctx = NULL;
335
310 wordsplit_init0 (wsp); 336 wordsplit_init0 (wsp);
311 337
312 return 0; 338 return 0;
@@ -1575,7 +1601,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
1575 } 1601 }
1576 else if (wsp->ws_flags & WRDSF_UNDEF) 1602 else if (wsp->ws_flags & WRDSF_UNDEF)
1577 { 1603 {
1578 _wsplt_seterr (wsp, WRDSE_UNDEF); 1604 _wsplt_setctxerr (wsp, WRDSE_UNDEF, str, *pend - str + 1);
1579 return 1; 1605 return 1;
1580 } 1606 }
1581 else 1607 else
@@ -1680,7 +1706,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
1680static int 1706static int
1681begin_var_p (int c) 1707begin_var_p (int c)
1682{ 1708{
1683 return memchr("{#@*", c, 4) != NULL || ISVARBEG (c) || ISDIGIT (c); 1709 return memchr ("{#@*", c, 4) != NULL || ISVARBEG (c) || ISDIGIT (c);
1684} 1710}
1685 1711
1686static int 1712static int
@@ -2098,7 +2124,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
2098 2124
2099 default: 2125 default:
2100 free (pattern); 2126 free (pattern);
2101 return _wsplt_seterr (wsp, WRDSE_GLOBERR); 2127 return _wsplt_setctxerr (wsp, WRDSE_GLOBERR, pattern, slen);
2102 } 2128 }
2103 2129
2104 prev = p; 2130 prev = p;
@@ -2754,12 +2780,17 @@ wordsplit_clearerr (struct wordsplit *ws)
2754 if (ws->ws_errno == WRDSE_USERERR) 2780 if (ws->ws_errno == WRDSE_USERERR)
2755 free (ws->ws_usererr); 2781 free (ws->ws_usererr);
2756 ws->ws_usererr = NULL; 2782 ws->ws_usererr = NULL;
2783
2784 free (ws->ws_errctx);
2785 ws->ws_errctx = NULL;
2786
2757 ws->ws_errno = WRDSE_OK; 2787 ws->ws_errno = WRDSE_OK;
2758} 2788}
2759 2789
2760void 2790void
2761wordsplit_free (struct wordsplit *ws) 2791wordsplit_free (struct wordsplit *ws)
2762{ 2792{
2793 wordsplit_clearerr (ws);
2763 wordsplit_free_nodes (ws); 2794 wordsplit_free_nodes (ws);
2764 wordsplit_free_words (ws); 2795 wordsplit_free_words (ws);
2765 free (ws->ws_wordv); 2796 free (ws->ws_wordv);
@@ -2823,6 +2854,9 @@ wordsplit_perror (struct wordsplit *wsp)
2823 break; 2854 break;
2824 2855
2825 default: 2856 default:
2826 wsp->ws_error ("%s", wordsplit_strerror (wsp)); 2857 if (wsp->ws_errctx)
2858 wsp->ws_error ("%s: %s", wordsplit_strerror (wsp), wsp->ws_errctx);
2859 else
2860 wsp->ws_error ("%s", wordsplit_strerror (wsp));
2827 } 2861 }
2828} 2862}
diff --git a/tests/wordsplit.at b/tests/wordsplit.at
index 0a7d7db..7ecc016 100644
--- a/tests/wordsplit.at
+++ b/tests/wordsplit.at
@@ -238,7 +238,7 @@ TOTAL: 0
238TESTWSP([bail out on undefined variables],[],[-undef], 238TESTWSP([bail out on undefined variables],[],[-undef],
239[$FOO], 239[$FOO],
240[], 240[],
241[undefined variable 241[undefined variable: FOO
242], 242],
243[unset FOO;]) 243[unset FOO;])
244 244

Return to:

Send suggestions and report system problems to the System administrator.