zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: zsh-workers@zsh.org
Subject: Re: [bug] shwordsplit not working on $@ when $# > 1
Date: Mon, 8 Aug 2016 18:21:24 -0700	[thread overview]
Message-ID: <160808182124.ZM9355@torch.brasslantern.com> (raw)
In-Reply-To: <20160808192734.21923640@ntlworld.com>

On Aug 8,  7:27pm, Peter Stephenson wrote:
} Subject: Re: [bug] shwordsplit not working on $@ when $# > 1
}
} The variable isarr from the value entry v->isarr is negative, so we
} don't go into the loop that does joining and splitting as that
} explicitly asks for (isarr >= 0).  (It was 0 for a scalar, hence the
} first case above.)

It's not really a loop; it's just the "if" block at subst.c:3457.
This block first joins all the array elements on the first character
of $IFS, and then splits the resulting string on spaces.

The problem is that in this case we want split but in the case of
users/15439 we do NOT want join.  The patch called out by Jeremie
prevents the joining, but does so by bypassing the splitting; it
first sets nojoin nonzero by examining IFS, and then sets isarr = -1
when nojoin is true (i.e., the negative isarr you saw is not coming
from v->isarr, so the value of SCANPM_ISVAR_AT is a red herring).

The underlying assumption that it works to first join on $IFS and
then split again to get the array leads to the error, because when
$IFS is empty there won't be anything to split on, but when there is
no join the new array must be built by splitting every element of
the value array (and there is currently no code that does that).

I *think* we can untangle this as follows, but then again I thought
I had untangled in in workers/29313, too.  This relies on the idea
that if we already have an array when nojoin, then we're not going
to split it again, which seems dubious somehow if there is explicit
use of the (s:-:) flag.  It may be that we really do need to write
a loop over the existing elements when isarr is true there.

Existing tests still pass, but then they always did, this needs a
new one.  Holding off until we think of other edge cases.

diff --git a/Src/subst.c b/Src/subst.c
index e3af156..6dd4608 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -3454,13 +3454,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
      * exception is that ${name:-word} and ${name:+word} will have already
      * done any requested splitting of the word value with quoting preserved.
      */
-    if (ssub || (spbreak && isarr >= 0) || spsep || sep) {
-	if (isarr) {
+    if (ssub || spbreak || spsep || sep) {
+	if (isarr && !nojoin) {
 	    val = sepjoin(aval, sep, 1);
 	    isarr = 0;
 	    ms_flags = 0;
 	}
-	if (!ssub && (spbreak || spsep)) {
+	if (!ssub && (spbreak || spsep) && !isarr) {
 	    aval = sepsplit(val, spsep, 0, 1);
 	    if (!aval || !aval[0])
 		val = dupstring("");
@@ -3527,7 +3527,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
 	}
 	/*
 	 * TODO:  It would be really quite nice to abstract the
-	 * isarr and !issarr code into a function which gets
+	 * isarr and !isarr code into a function which gets
 	 * passed a pointer to a function with the effect of
 	 * the promptexpand bit.  Then we could use this for
 	 * a lot of stuff and bury val/aval/isarr inside a structure


  reply	other threads:[~2016-08-09  1:21 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-08 11:16 Stephane Chazelas
2016-08-08 17:28 ` Bart Schaefer
2016-08-08 18:02   ` Jérémie Roquet
2016-08-08 18:27 ` Peter Stephenson
2016-08-09  1:21   ` Bart Schaefer [this message]
2016-08-09  8:40     ` Peter Stephenson
2016-08-10 17:28       ` Bart Schaefer
2016-08-11 10:05         ` Peter Stephenson
2016-08-11 17:28           ` Bart Schaefer
2016-08-12  7:50             ` Bart Schaefer
2016-08-10 12:56     ` Peter Stephenson
2016-08-11  0:39       ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=160808182124.ZM9355@torch.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).