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

$(($...)) bugfix for hzoli releases



As Mark Borges noticed my releases has a problem with substitutions inside
math substitutions.  E.g.

% echo $(($1))
zsh: bad math expression: unbalanced stack

Note that it only occures with $((...)) and not with $[...].  Here is the fix.
I also moved a sanity check inside an #ifdef DEBUG ... #endif, and wrote some
better comments.

Cheers,
   Zoltan

*** 1.16	1995/09/22 18:57:05
--- Src/subst.c	1995/09/30 21:44:56
***************
*** 125,152 ****
  	    else
  		endchar = *str, *str = '\0';
  
! 	    /* echo ${(e)~foo} discards some special characters without	*
! 	     * the untokenization below. A single untokenize is not	*
! 	     * enough because of the silly quoting rules within `...`.	*/
! 	    while (*++str && *str != endchar)
! 		if (itok(*str) && *str != Nularg &&
! 		    !(endchar != Outpar && *str == Bnull &&
! 		      (str[1] == '$' || str[1] == '\\' || str[1] == '`' ||
! 		       (qt && str[1] == '"'))))
! 		    *str = ztokens[*str - Pound];
! 	    if (!*str) {
! 		/* This shoud never happen */
! 		zerr("Oops. parse error in command substitution", NULL, 0);
! 		return NULL;
! 	    }
  	    *str++ = '\0';
! 	    if (endchar == Outpar && str2[1] == '(' &&
! 		str[-2] == ')') {
  		/* Math substitution of the form $((...)) */
  		str = arithsubst(str2 + 1, &str3, str);
  		setdata(node, (void *) str3);
  		continue;
  	    }
  	    if (!(pl = getoutput(str2 + 1, qt || ssub))) {
  		zerr("parse error in command substitution", NULL, 0);
  		return NULL;
--- 125,161 ----
  	    else
  		endchar = *str, *str = '\0';
  
! 	    while (*++str != endchar)
! #ifdef DEBUG
! 		if (!*str) {
! 		    /* This shoud never happen */
! 		    zerr("Oops. parse error in command substitution", NULL, 0);
! 		    return NULL;
! 		}
! #else
! 		;
! #endif
  	    *str++ = '\0';
! 	    if (endchar == Outpar && str2[1] == '(' && str[-2] == ')') {
  		/* Math substitution of the form $((...)) */
  		str = arithsubst(str2 + 1, &str3, str);
  		setdata(node, (void *) str3);
  		continue;
  	    }
+ 
+ 	    /* It is a command substitution, which will be parsed again   *
+ 	     * by the lexer, so we untokenize it first, but we cannot use *
+ 	     * untokenize() since in the case of `...` some Bnulls should *
+ 	     * be left unchanged.  Note that the lexer doesn't tokenize   *
+ 	     * the body of a command substitution so if there are some    *
+ 	     * tokens here they are from a ${(e)~...} substitution.       */
+ 	    for (str = str2; *++str; )
+ 		if (itok(*str) && *str != Nularg &&
+ 		    !(endchar != Outpar && *str == Bnull &&
+ 		      (str[1] == '$' || str[1] == '\\' || str[1] == '`' ||
+ 		       (qt && str[1] == '"'))))
+ 		    *str = ztokens[*str - Pound];
+ 	    str++;
  	    if (!(pl = getoutput(str2 + 1, qt || ssub))) {
  		zerr("parse error in command substitution", NULL, 0);
  		return NULL;



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