summaryrefslogtreecommitdiff
path: root/Src/utils.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2006-09-13 20:55:29 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2006-09-13 20:55:29 +0000
commita242b1eb35863b73cbc63699fafe920e8b92c858 (patch)
tree141db2c3c4a20d1a44d7fe357a39d0ba4aab9d4f /Src/utils.c
parentefd061cdc9bdc0ba692387ec25eb6d01616d0425 (diff)
downloadzsh-a242b1eb35863b73cbc63699fafe920e8b92c858.tar.gz
zsh-a242b1eb35863b73cbc63699fafe920e8b92c858.zip
22705: make ${(l...)...} and ${(r...)...} handle multibyte characters
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c88
1 files changed, 31 insertions, 57 deletions
diff --git a/Src/utils.c b/Src/utils.c
index a72ddfcc5..37017bdc7 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -524,8 +524,12 @@ wcs_nicechar(wchar_t c, size_t *widthp, char **swidep)
return buf;
}
- if (widthp)
- *widthp = (s - buf) + wcwidth(c);
+ if (widthp) {
+ int wcw = wcwidth(c);
+ *widthp = (s - buf);
+ if (wcw > 0)
+ *widthp += wcw;
+ }
if (swidep)
*swidep = s;
for (mbptr = mbstr; ret; s++, mbptr++, ret--) {
@@ -539,6 +543,22 @@ wcs_nicechar(wchar_t c, size_t *widthp, char **swidep)
*s = 0;
return buf;
}
+
+/**/
+mod_export int
+zwcwidth(wint_t wc)
+{
+ int wcw;
+ /* assume a single-byte character if not valid */
+ if (wc == WEOF)
+ return 1;
+ wcw = wcwidth(wc);
+ /* if not printable, assume zero width */
+ if (wcw <= 0)
+ return 0;
+ return wcw;
+}
+
/**/
#endif /* MULTIBYTE_SUPPORT */
@@ -3953,58 +3973,6 @@ nicedup(const char *s, int heap)
return retstr;
}
-/*
- * Return the screen width of a multibyte string. The input
- * string is metafied.
- */
-/**/
-mod_export int
-mb_width(const char *s)
-{
- char *ums = ztrdup(s), *umptr;
- int umlen, eol = 0;
- int width = 0;
- mbstate_t mbs;
-
- memset(&mbs, 0, sizeof mbs);
- umptr = unmetafy(ums, &umlen);
- /*
- * Convert one wide character at a time. We could convet
- * the entire string using mbsrtowcs(), but that terminates on
- * a NUL and we might have embedded NULs.
- */
- while (umlen > 0) {
- int wret;
- wchar_t cc;
- size_t cnt = eol ? MB_INVALID : mbrtowc(&cc, umptr, umlen, &mbs);
-
- switch (cnt) {
- case MB_INCOMPLETE:
- eol = 1;
- /* FALL THROUGH */
- case MB_INVALID:
- memset(&mbs, 0, sizeof mbs);
- /* FALL THROUGH */
- case 0:
- /* Assume a single-width character. */
- width++;
- cnt = 1;
- break;
- default:
- wret = wcwidth(cc);
- if (wret > 0)
- width += wret;
- break;
- }
-
- umlen -= cnt;
- umptr += cnt;
- }
-
- free(ums);
-
- return width;
-}
/*
* Length of metafied string s which contains the next multibyte
@@ -4107,9 +4075,15 @@ mb_metastrlen(char *ptr, int width)
memset(&mb_shiftstate, 0, sizeof(mb_shiftstate));
ptr = laststart + (*laststart == Meta) + 1;
num++;
- } else if (width)
- num += wcwidth(wc);
- else
+ } else if (width) {
+ /*
+ * Returns -1 if not a printable character; best
+ * just to ignore these.
+ */
+ int wcw = wcwidth(wc);
+ if (wcw > 0)
+ num += wcw;
+ } else
num++;
laststart = ptr;
num_in_char = 0;