diff options
-rw-r--r-- | include/wordsplit.h | 6 | ||||
-rw-r--r-- | src/wordsplit.c | 42 | ||||
-rw-r--r-- | tests/wordsplit.at | 2 |
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 | ||
110 | static 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 | |||
127 | static 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 | |||
110 | static int wordsplit_run (const char *command, size_t length, | 134 | static 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, | |||
1680 | static int | 1706 | static int |
1681 | begin_var_p (int c) | 1707 | begin_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 | ||
1686 | static int | 1712 | static 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 | ||
2760 | void | 2790 | void |
2761 | wordsplit_free (struct wordsplit *ws) | 2791 | wordsplit_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 | |||
238 | TESTWSP([bail out on undefined variables],[],[-undef], | 238 | TESTWSP([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 | ||