diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Doc/Zsh/expn.yo | 5 | ||||
-rw-r--r-- | Src/subst.c | 43 |
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 |