diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | Doc/Zsh/expn.yo | 3 | ||||
-rw-r--r-- | Src/subst.c | 39 |
3 files changed, 31 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog index 5d88aff9b..7f8a29e2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2006-06-28 Peter Stephenson <pws@csr.com> + * 22526: Doc/Zsh/expn.yo, Src/subst.c: enhance${(#)...} to output + Unicode. + * 22525: Completion/compinit, Src/hist.c, Src/jobs.c, Src/pattern.c, Src/subst.c, Src/utils.c, Src/zsh.h, Test/D07multibyte.ztst: lengths and cases of multibyte strings diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 146750098..fe16af735 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -649,6 +649,9 @@ 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. + +If the tt(MULTIBYTE) option is set and the number is greater than 127 +(i.e. not an ASCII character) it is treated as a Unicode character. ) item(tt(%))( Expand all tt(%) escapes in the resulting words in the same way as in in diff --git a/Src/subst.c b/Src/subst.c index d69f34c4b..12df115a0 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -889,6 +889,29 @@ subst_parse_str(char **sp, int single, int err) return 1; } +/* Evaluation for (#) flag */ + +static char * +substevalchar(char *ptr) +{ + zlong ires = mathevali(ptr); + + if (errflag) + return NULL; + if (isset(MULTIBYTE) && ires > 127) { + char buf[10]; + int dummy; + + /* inefficient: should separate out \U handling from getkeystring */ + sprintf(buf, "\\U%.8x", (unsigned int)ires); + return getkeystring(buf, &dummy, 2, NULL); + } else { + ptr = zhalloc(2); + sprintf(ptr, "%c", (int)ires); + return ptr; + } +} + /* parameter substitution */ #define isstring(c) ((c) == '$' || (char)(c) == String || (char)(c) == Qstring) @@ -2269,13 +2292,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) /* * 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; @@ -2283,20 +2300,14 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) for (avptr = aval, av2ptr = aval2; *avptr; avptr++, av2ptr++) { - ires = mathevali(*avptr); - if (errflag) + if (!(*av2ptr = substevalchar(*avptr))) return NULL; - *av2ptr = zhalloc(2); - sprintf(*av2ptr, "%c", (int)ires); } *av2ptr = NULL; aval = aval2; } else { - ires = mathevali(val); - if (errflag) + if (!(val = substevalchar(val))) return NULL; - val = zhalloc(2); - sprintf(val, "%c", (int)ires); } } /* |