diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2008-01-22 10:14:01 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2008-01-22 10:14:01 +0000 |
commit | 088e8a9c8d19d0675bde3fabdde1b1e35129725b (patch) | |
tree | 0fadfdafe4b88d9cff83a5d74eb58778f60fd0ee /Src/Zle | |
parent | a199833e23147036edfcddfc3ab2752c7c20a686 (diff) | |
download | zsh-088e8a9c8d19d0675bde3fabdde1b1e35129725b.tar.gz zsh-088e8a9c8d19d0675bde3fabdde1b1e35129725b.tar.xz zsh-088e8a9c8d19d0675bde3fabdde1b1e35129725b.zip |
24434: handle unprintable and zero-width wide characters
by displaying as hex
Diffstat (limited to 'Src/Zle')
-rw-r--r-- | Src/Zle/zle_refresh.c | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index cdda42287..3f3de2c68 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -447,6 +447,10 @@ zrefresh(void) int tmpalloced; /* flag to free tmpline when finished */ int remetafy; /* flag that zle line is metafied */ struct rparams rpms; +#ifdef MULTIBYTE_SUPPORT + int width; /* width of wide character */ +#endif + /* If this is called from listmatches() (indirectly via trashzle()), and * * that was called from the end of zrefresh(), then we don't need to do * @@ -633,8 +637,7 @@ zrefresh(void) while ((++t0) & 7); } #ifdef MULTIBYTE_SUPPORT - else if (iswprint(*t)) { - int width = wcwidth(*t); + else if (iswprint(*t) && (width = wcwidth(*t)) > 0) { if (width > rpms.sen - rpms.s) { /* * Too wide to fit. Insert spaces to end of current line. @@ -649,7 +652,7 @@ zrefresh(void) rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln]; } } - if (width > rpms.sen - rpms.s) { + if (width > rpms.sen - rpms.s || width == 0) { /* * The screen width is too small to fit even one * occurrence. @@ -663,7 +666,11 @@ zrefresh(void) } } #endif - else if (ZC_icntrl(*t)) { /* other control character */ + else if (ZC_icntrl(*t) +#ifdef MULTIBYTE_SUPPORT + && (unsigned)*t <= 0xffU +#endif + ) { /* other control character */ *rpms.s++ = ZWC('^'); if (rpms.s == rpms.sen) { /* text wrapped */ @@ -671,9 +678,42 @@ zrefresh(void) break; } *rpms.s++ = (((unsigned int)*t & ~0x80u) > 31) ? ZWC('?') : (*t | ZWC('@')); - } else { /* normal character */ + } +#ifdef MULTIBYTE_SUPPORT + else { + /* + * Not printable or zero width. + * Resort to hackery. + */ + char dispchars[11]; + char *dispptr = dispchars; + wchar_t wc; + + if ((unsigned)*t > 0xffffU) { + sprintf(dispchars, "<%.08x>", (unsigned)*t); + } else { + sprintf(dispchars, "<%.04x>", (unsigned)*t); + } + while (*dispptr) { + if (mbtowc(&wc, dispptr, 1) == 1 /* paranoia */) + { + *rpms.s++ = wc; + if (rpms.s == rpms.sen) { + /* text wrapped */ + if (nextline(&rpms, 1)) + break; + } + } + dispptr++; + } + if (*dispptr) /* nextline said stop processing */ + break; + } +#else + else { /* normal character */ *rpms.s++ = *t; } +#endif if (rpms.s == rpms.sen) { /* text wrapped */ if (nextline(&rpms, 1)) |