diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-05-14 22:25:26 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-05-14 22:25:26 +0300 |
commit | 1658f5685bd396ce6bfd8e4822f4a9363eb4a4c9 (patch) | |
tree | ee5e39a9f040691da09b9a569b6f000d11e1ca6a /src | |
parent | 39beda10e855d265b5af74ea53a5d7a89a91296a (diff) | |
download | grecs-1658f5685bd396ce6bfd8e4822f4a9363eb4a4c9.tar.gz grecs-1658f5685bd396ce6bfd8e4822f4a9363eb4a4c9.tar.bz2 |
Fix behaviour of $* and $@ in quoted context
Diffstat (limited to 'src')
-rw-r--r-- | src/wordsplit.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c index f563725..4e633fa 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c @@ -253,12 +253,15 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len, if (!(wsp->ws_flags & WRDSF_DOOFFS)) wsp->ws_offs = 0; if (!(wsp->ws_flags & WRDSF_DELIM)) wsp->ws_delim = " \t\n"; + wsp->ws_sep[0] = wsp->ws_delim[0]; + wsp->ws_sep[1] = 0; + if (!(wsp->ws_flags & WRDSF_COMMENT)) wsp->ws_comment = NULL; if (!(wsp->ws_flags & WRDSF_CLOSURE)) wsp->ws_closure = NULL; @@ -346,13 +349,13 @@ alloc_space (struct wordsplit *wsp, size_t count) #define _WSNF_WORD 0x02 /* node contains word in v.word */ #define _WSNF_QUOTE 0x04 /* text is quoted */ #define _WSNF_NOEXPAND 0x08 /* text is not subject to expansion */ #define _WSNF_JOIN 0x10 /* node must be joined with the next node */ #define _WSNF_SEXP 0x20 /* is a sed expression */ #define _WSNF_DELIM 0x40 /* node is a delimiter */ - +#define _WSNF_CONST 0x80 /* with _WSNF_WORD: v.word is constant */ #define _WSNF_EMPTYOK 0x0100 /* special flag indicating that wordsplit_add_segm must add the segment even if it is empty */ struct wordsplit_node { @@ -438,13 +441,13 @@ wsnode_new (struct wordsplit *wsp, struct wordsplit_node **pnode) return 0; } static void wsnode_free (struct wordsplit_node *p) { - if (p->flags & _WSNF_WORD) + if ((p->flags & (_WSNF_WORD|_WSNF_CONST)) == _WSNF_WORD) free (p->v.word); free (p); } static void wsnode_append (struct wordsplit *wsp, struct wordsplit_node *node) @@ -1247,12 +1250,13 @@ expand_paramv (struct wordsplit *wsp, struct wordsplit_node **ptail, int flg, { struct wordsplit ws; int wsflags = WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE | (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0) | (q ? WRDSF_NOSPLIT : 0); size_t i; + struct wordsplit_node *tail = *ptail; 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]), @@ -1285,12 +1289,34 @@ expand_paramv (struct wordsplit *wsp, struct wordsplit_node **ptail, int flg, } wsflags |= WRDSF_REUSE; } if (wsflags & WRDSF_REUSE) wordsplit_free (&ws); + + if (flg & _WSNF_QUOTE) + { + tail = tail->next; + /* Insert delimiters, mark nodes as joinable */ + while (tail != *ptail) + { + struct wordsplit_node *next = tail->next; + struct wordsplit_node *newnode; + + tail->flags |= _WSNF_JOIN; + + if (wsnode_new (wsp, &newnode)) + return 1; + newnode->flags = _WSNF_WORD | _WSNF_CONST | _WSNF_NOEXPAND | _WSNF_JOIN; + newnode->v.word = wsp->ws_sep; + + wsnode_insert (wsp, newnode, tail, 0); + tail = next; + } + } + return 0; } static int expvar (struct wordsplit *wsp, const char *str, size_t len, struct wordsplit_node **ptail, const char **pend, int flg) |