about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2005-11-01 18:04:24 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2005-11-01 18:04:24 +0000
commitf42d15278dbdfa185b24e17f228be0c8c59a9c44 (patch)
treee0331939f2e62427f79c0ce9eb148c341636cd9a
parentf53996f14b0dc2a5733440d92f614aa36d07e9fd (diff)
downloadzsh-f42d15278dbdfa185b24e17f228be0c8c59a9c44.tar.gz
zsh-f42d15278dbdfa185b24e17f228be0c8c59a9c44.tar.xz
zsh-f42d15278dbdfa185b24e17f228be0c8c59a9c44.zip
21967: add ${(#)...} substitution
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/expn.yo5
-rw-r--r--Src/subst.c43
3 files changed, 53 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 2bc2b368a..2d0e10d9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2005-11-01  Peter Stephenson  <pws@csr.com>
+
+	* 21967 (docmentation tweaked): Doc/Zsh/expn.yo, Src/subst.c:
+	${(#)foo} uses matheval to produce characters.
+
 2005-10-31  Wayne Davison  <wayned@users.sourceforge.net>
 
 	* 21949 (modified): Src/zsh.h, Src/Zle/zle.h, Src/Zle/zle_misc.c,
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 60c74cab1..c05796a94 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -632,6 +632,11 @@ means the same thing as the more readable `(tt(%%qqq))'.  The
 following flags are supported:
 
 startitem()
+item(tt(#))(
+Evaluate the resulting words as numeric expressions and output the
+characters corresponding to the resulting integer.  Note that this form is
+entirely distinct from use of the tt(#) without parentheses.
+)
 item(tt(%))(
 Expand all tt(%) escapes in the resulting words in the same way as in in
 prompts (see noderef(Prompt Expansion)). If this flag is given twice,
diff --git a/Src/subst.c b/Src/subst.c
index a10e2ee22..d92be8f89 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -915,6 +915,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
      */
     int globsubst = isset(GLOBSUBST);
     /*
+     * Indicates ${(#)...}.
+     */
+    int evalchar = 0;
+    /*
      * Indicates ${#pm}, massaged by whichlen which is set by
      * the (c), (w), and (W) flags to indicate how we take the length.
      */
@@ -1320,6 +1324,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		    unique = 1;
 		    break;
 
+		case '#':
+		case Pound:
+		    evalchar = 1;
+		    break;
+
 		default:
 		  flagerr:
 		    zerr("error in flags", NULL, 0);
@@ -2233,6 +2242,40 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
     }
     if (errflag)
 	return NULL;
+    if (evalchar) {
+	/*
+	 * Evaluate the value numerically and output the result as
+	 * a character.
+	 *
+	 * Note this doesn't yet handle Unicode or multibyte characters:
+	 * that will need handling more generally probably by
+	 * an additional flag of some sort.
+	 */
+	zlong ires;
+
+	if (isarr) {
+	    char **aval2, **avptr, **av2ptr;
+
+	    aval2 = (char **)zhalloc((arrlen(aval)+1)*sizeof(char *));
+
+	    for (avptr = aval, av2ptr = aval2; *avptr; avptr++, av2ptr++)
+	    {
+		ires = mathevali(*avptr);
+		if (errflag)
+		    return NULL;
+		*av2ptr = zhalloc(2);
+		sprintf(*av2ptr, "%c", (int)ires);
+	    }
+	    *av2ptr = NULL;
+	    aval = aval2;
+	} else {
+	    ires = mathevali(val);
+	    if (errflag)
+		return NULL;
+	    val = zhalloc(2);
+	    sprintf(val, "%c", (int)ires);
+	}
+    }
     /*
      * This handles taking a length with ${#foo} and variations.
      * TODO: again. one might naively have thought this had the