summaryrefslogtreecommitdiff
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.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