diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-05-15 16:37:09 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-05-15 16:37:09 +0300 |
commit | 20899f652a904b510b2c7d3507b75d1399416485 (patch) | |
tree | 44f221b132d16f229fb991a03451d7039fb5f726 | |
parent | 7dbea4b03426d8a81dbc6563b96aa760e719f5a8 (diff) | |
download | grecs-20899f652a904b510b2c7d3507b75d1399416485.tar.gz grecs-20899f652a904b510b2c7d3507b75d1399416485.tar.bz2 |
wordsplit: introduce error context
* include/wordsplit.h (wordsplit) <ws_errctx>: New field.
* src/wordsplit.c (wordsplit_init): Initialize ws_errctx.
(expvar,wordsplit_pathexpand): Save error context.
(wordsplit_clearerr): Free error context.
(wordsplit_perror): Use error context if available.
* tests/wordsplit.at: Reflect changes.
-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 @@ -112,3 +112,3 @@ struct wordsplit - 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. */ @@ -120,2 +120,6 @@ struct wordsplit 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; diff --git a/src/wordsplit.c b/src/wordsplit.c index af747b3..6dba914 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c @@ -109,2 +109,26 @@ _wsplt_nomem (struct wordsplit *wsp) +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, @@ -309,2 +333,4 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len, + wsp->ws_errctx = NULL; + wordsplit_init0 (wsp); @@ -1577,3 +1603,3 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, { - _wsplt_seterr (wsp, WRDSE_UNDEF); + _wsplt_setctxerr (wsp, WRDSE_UNDEF, str, *pend - str + 1); return 1; @@ -1682,3 +1708,3 @@ begin_var_p (int c) { - return memchr("{#@*", c, 4) != NULL || ISVARBEG (c) || ISDIGIT (c); + return memchr ("{#@*", c, 4) != NULL || ISVARBEG (c) || ISDIGIT (c); } @@ -2100,3 +2126,3 @@ wordsplit_pathexpand (struct wordsplit *wsp) free (pattern); - return _wsplt_seterr (wsp, WRDSE_GLOBERR); + return _wsplt_setctxerr (wsp, WRDSE_GLOBERR, pattern, slen); } @@ -2756,2 +2782,6 @@ wordsplit_clearerr (struct wordsplit *ws) ws->ws_usererr = NULL; + + free (ws->ws_errctx); + ws->ws_errctx = NULL; + ws->ws_errno = WRDSE_OK; @@ -2762,2 +2792,3 @@ wordsplit_free (struct wordsplit *ws) { + wordsplit_clearerr (ws); wordsplit_free_nodes (ws); @@ -2825,3 +2856,6 @@ wordsplit_perror (struct wordsplit *wsp) 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 @@ -240,3 +240,3 @@ TESTWSP([bail out on undefined variables],[],[-undef], [], -[undefined variable +[undefined variable: FOO ], |