Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm
Precedence: bulk
X-No-Archive: yes
List-Id: Zsh Workers List <zsh-workers.zsh.org>
List-Post: <mailto:zsh-workers@zsh.org>
List-Help: <mailto:zsh-workers-help@zsh.org>
X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au
X-Spam-Level: 
X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_DKIM_INVALID
	autolearn=ham autolearn_force=no version=3.4.1
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=brasslantern-com.20150623.gappssmtp.com; s=20150623;
        h=from:message-id:date:in-reply-to:comments:references:to:subject
         :mime-version:content-type;
        bh=GC11XM7apBj4dRLI0SpJXI54J+mPJEmt5UV8dGyrwsc=;
        b=mx3Ni1Q81YFG839DuC5sQ4ZIQ4kdpBMv6weG5BbAYY62D81YC8cNHFtaEdlEQN1ANZ
         /3ljupA6wzB/Je8+EgKiV0aAT8QIoEEPAvxhqRDg8JZuM4qGbfUEWAGH8P/yciIsTXm5
         hRHgogVCfW6Hb5c50sG+gzYwP+IBVBlu88iGR7S9GEw7FBdFeLryl90T3uReBarJbHZE
         noXjBJFWHzJjc4AsVwLRYbO0xqMzOSE3MrZJTY+spZNL0pUlZH6h5MWNy6VrcMRXDgIn
         +m+gdULJGW8Wgr3ZHehJdA9RqDOZWacngTFQqwpO1//hdJehEoOxWv49M7gO3Cjzgfo7
         +m6Q==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:from:message-id:date:in-reply-to:comments
         :references:to:subject:mime-version:content-type;
        bh=GC11XM7apBj4dRLI0SpJXI54J+mPJEmt5UV8dGyrwsc=;
        b=iqo6p8bGZVdXlUf8r2jhQ0El43k3Z93OTfrNKD9kU0wlxBZzvoRgvbeSL85RC6lA8b
         JrXwsuPfCCBaQQ7Vyp8MlmLZ7Y3eRPdzD7vpuP5ZlZxERYz1JlQ/eb0pL/Og6y/ogxrk
         iL9zSXDCL10PyN/+I74IQKEzAyy8hvA/MsA5dl/eOmQvA7VuORiUwC0VaAoZcmRfNIRt
         hLhVVcz5YIVPE9S5V99fHq9ylXhhvLAshIUzoz2VUa0xocG4yXsK/vC8duJ44eXj8s/l
         c76BBfeRltkv8zz+K7AE741iop3sUBTm6bMr8EWmynSPI42rsD9K2saV5gaZ41VvrQzf
         6OVQ==
X-Gm-Message-State: AG10YOTyc2Ac0rDT+gGByqJFaErSfkO95j/tpH3bIacyW3hVsuLqx7U96WAtGot+vbk+fg==
X-Received: by 10.98.11.134 with SMTP id 6mr40815785pfl.109.1454915139272;
        Sun, 07 Feb 2016 23:05:39 -0800 (PST)
From: Bart Schaefer <schaefer@brasslantern.com>
Message-Id: <160207230544.ZM10065@torch.brasslantern.com>
Date: Sun, 7 Feb 2016 23:05:44 -0800
In-Reply-To: <160207133307.ZM31008@torch.brasslantern.com>
Comments: In reply to Bart Schaefer <schaefer@brasslantern.com>
        "Re: unset "hash[key]" isn't matched with what "key" may be" (Feb  7,  1:33pm)
References: <CAKc7PVBXd-UGwM+_tRSwuw-WL154YaTys6-t3iuzfAsG-RC-YQ@mail.gmail.com> 
	<160207133307.ZM31008@torch.brasslantern.com>
X-Mailer: OpenZMail Classic (0.9.2 24April2005)
To: Zsh hackers list <zsh-workers@zsh.org>
Subject: Re: unset "hash[key]" isn't matched with what "key" may be
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
X-Seq: zsh-workers 37914

On Feb 7,  1:33pm, Bart Schaefer wrote:
}
} On Feb 7,  3:16pm, Sebastian Gniazdowski wrote:
} }                 unset "func[$i]"
} } -zplg-diff-functions:unset:36: func[opp+a\[]: invalid parameter name
} 
} Yep, "unset" is pretty naive about parsing the subscript there.  It wants
} the square brackets in balanced pairs and doesn't consider any kind of
} quoting.

Patch below for consideration.  This doesn't do any additional expansion,
but it has the effect of allowing backslash-quoting -- which therefore
requires that backslashes themselves be doubled, cf. all the caveats
about subscripts behaving as if double-quoted that appear elsewhere.

After this patch, the best way to handle unset of associative array
elements looks something like

  typeset -A ary
  ary[${key}]=value
  ...
  unset "ary[${(b)key}]"

(or use "noglob" instead of double quotes).

This does reflect a change from previous behavior, so we'll want to
consider it carefully.  If we decide to keep the old behavior, just
remove the call to remnulargs().  I think using parse_subscript() intead
of skipcomm() is still the more sensible approach; in fact, this patch
revealed an error in the E01 test script.

} (The -m option also doesn't work for subscripts.)

I haven't attempted to do anything about that, and I'm not sure that it
makes sense to.


diff --git a/Src/builtin.c b/Src/builtin.c
index 63f964d..4c8fbcd 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -3350,15 +3350,24 @@ bin_unset(char *name, char **argv, Options ops, int func)
     /* do not glob -- unset the given parameter */
     queue_signals();
     while ((s = *argv++)) {
-	char *ss = strchr(s, '[');
-	char *sse = ss;
+	char *ss = strchr(s, '['), *subscript = 0;
 	if (ss) {
-	    if (skipparens('[', ']', &sse) || *sse) {
-		zerrnam(name, "%s: invalid parameter name", s);
-		returnval = 1;
-		continue;
-	    }
+	    char *sse;
 	    *ss = 0;
+	    if ((sse = parse_subscript(ss+1, 1, ']'))) {
+		*sse = 0;
+		subscript = dupstring(ss+1);
+		*sse = ']';
+		remnulargs(subscript);
+		untokenize(subscript);
+	    }
+	}
+	if ((ss && !subscript) || !isident(s)) {
+	    if (ss)
+		*ss = '[';
+	    zerrnam(name, "%s: invalid parameter name", s);
+	    returnval = 1;
+	    continue;
 	}
 	pm = (Param) (paramtab == realparamtab ?
 		      /* getnode2() to avoid autoloading */
@@ -3376,11 +3385,8 @@ bin_unset(char *name, char **argv, Options ops, int func)
 	} else if (ss) {
 	    if (PM_TYPE(pm->node.flags) == PM_HASHED) {
 		HashTable tht = paramtab;
-		if ((paramtab = pm->gsu.h->getfn(pm))) {
-		    *--sse = 0;
-		    unsetparam(ss+1);
-		    *sse = ']';
-		}
+		if ((paramtab = pm->gsu.h->getfn(pm)))
+		    unsetparam(subscript);
 		paramtab = tht;
 	    } else if (PM_TYPE(pm->node.flags) == PM_SCALAR ||
 		       PM_TYPE(pm->node.flags) == PM_ARRAY) {
diff --git a/Test/E01options.ztst b/Test/E01options.ztst
index f270767..40e96af 100644
--- a/Test/E01options.ztst
+++ b/Test/E01options.ztst
@@ -776,7 +776,7 @@
   unsetopt pathdirs
   pathtestdir/findme
   path=($oldpath)
-  unset $oldpath
+  unset oldpath
   rm -rf pdt_topdir pathtestdir
 0:PATH_DIRS option
 >File in upper dir

