diff options
Diffstat (limited to 'Src/subst.c')
-rw-r--r-- | Src/subst.c | 43 |
1 files changed, 43 insertions, 0 deletions
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 |