Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Can't call multi-arg math function from array subscript



On Sun, 2 Apr 2017 11:51:56 -0700
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> Add another argument and strange things start happening:
> 
> % twoarg() { return $(( $2 - $1 )) }
> % functions -M twoarg
> % print ${string[1,twoarg(1,4)]}
> twoarg: bad math expression: operand expected at end of string
> twoarg: bad math expression: operand expected at end of string

It's going to be because getarg() doesn't do much parsing.  The answer
will be something like this, though I'm not sure what to do about
quoting.

pws

diff --git a/Src/params.c b/Src/params.c
index 785b9ea..a9683a6 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -1183,7 +1183,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
        int *prevcharlen, int *nextcharlen)
 {
     int hasbeg = 0, word = 0, rev = 0, ind = 0, down = 0, l, i, ishash;
-    int keymatch = 0, needtok = 0, arglen, len;
+    int keymatch = 0, needtok = 0, arglen, len, inpar = 0;
     char *s = *str, *sep = NULL, *t, sav, *d, **ta, **p, *tt, c;
     zlong num = 1, beg = 0, r = 0, quote_arg = 0;
     Patprog pprog = NULL;
@@ -1322,8 +1322,9 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
     }
 
     for (t = s, i = 0;
-	 (c = *t) && ((c != Outbrack &&
-		       (ishash || c != ',')) || i); t++) {
+	 (c = *t) &&
+	     ((c != Outbrack && (ishash || c != ',')) || i || inpar);
+	 t++) {
 	/* Untokenize inull() except before brackets and double-quotes */
 	if (inull(c)) {
 	    c = t[1];
@@ -1344,6 +1345,10 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
 	    i++;
 	else if (c == ']' || c == Outbrack)
 	    i--;
+	if (c == '(' || c == Inpar)
+	    inpar++;
+	else if (c == ')' || c == Outpar)
+	    inpar--;
 	if (ispecial(c))
 	    needtok = 1;
     }
diff --git a/Test/D06subscript.ztst b/Test/D06subscript.ztst
index 1449236..f0a858b 100644
--- a/Test/D06subscript.ztst
+++ b/Test/D06subscript.ztst
@@ -266,3 +266,10 @@
 >of the gang
 >of the gang
 >of the gang
+
+ string='abcde'
+ twoarg() { return $(( $2 - $1 )) }
+ functions -M twoarg
+ print ${string[1,twoarg(1,4)]}
+0:Commas inside parentheses do not confuse subscripts
+>abc



Messages sorted by: Reverse Date, Date, Thread, Author