diff options
author | Peter Stephenson <pws@zsh.org> | 2017-10-13 18:17:09 +0100 |
---|---|---|
committer | Peter Stephenson <pws@zsh.org> | 2017-10-13 18:17:09 +0100 |
commit | b3fa5c528c79b27986a77c92a48b7f70e7f9e7d3 (patch) | |
tree | a7aba1e9bf6b5549111a388a9835db091faf9122 /Src | |
parent | 57cfa8b160d16a37fcd6a5da7c8bcd492c76021e (diff) | |
download | zsh-b3fa5c528c79b27986a77c92a48b7f70e7f9e7d3.tar.gz zsh-b3fa5c528c79b27986a77c92a48b7f70e7f9e7d3.tar.xz zsh-b3fa5c528c79b27986a77c92a48b7f70e7f9e7d3.zip |
41877: Separate out SH_FILE_EXPANSION loop from parameter substitution.
Parameter substitution can add nodes that need to be rescanned by it, but not by file expansion, so the two don't play well together.
Diffstat (limited to 'Src')
-rw-r--r-- | Src/subst.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/Src/subst.c b/Src/subst.c index 8c290cccf..d027e3d83 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -108,7 +108,6 @@ prefork(LinkList list, int flags, int *ret_flags) queue_signals(); node = firstnode(list); while (node) { - LinkNode nextnode = 0; if ((flags & (PREFORK_SINGLE|PREFORK_ASSIGN)) == PREFORK_ASSIGN && (insnode = keyvalpairelement(list, node))) { node = insnode; @@ -137,23 +136,31 @@ prefork(LinkList list, int flags, int *ret_flags) * testing if cptr changed... */ setdata(node, cptr); - /* - * Advance now because we must not expand filenames again - * after string substitution (which may insert new nodes). - */ - nextnode = node; - incnode(nextnode); - } - if (!(node = stringsubst(list, node, - flags & ~(PREFORK_TYPESET|PREFORK_ASSIGN), - ret_flags, asssub))) { - unqueue_signals(); - return; } - if (isset(SHFILEEXPANSION)) - node = nextnode; else - incnode(node); + { + if (!(node = stringsubst(list, node, + flags & ~(PREFORK_TYPESET|PREFORK_ASSIGN), + ret_flags, asssub))) { + unqueue_signals(); + return; + } + } + incnode(node); + } + if (isset(SHFILEEXPANSION)) { + /* + * stringsubst() may insert new nodes, so doesn't work + * well in the same loop as file expansion. + */ + for (node = firstnode(list); node; incnode(node)) { + if (!(node = stringsubst(list, node, + flags & ~(PREFORK_TYPESET|PREFORK_ASSIGN), + ret_flags, asssub))) { + unqueue_signals(); + return; + } + } } for (node = firstnode(list); node; incnode(node)) { if (node == stop) |