summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWayne Davison <wayned@users.sourceforge.net>2006-01-12 00:51:41 +0000
committerWayne Davison <wayned@users.sourceforge.net>2006-01-12 00:51:41 +0000
commiteebfabe5487484b3d1e732386989e739bd3d869e (patch)
tree19cdbeb790de7a05bb770a7ea322867e45442c24
parent3039f65d741f2d9241528c1ea0a7af0b6dfcfd64 (diff)
downloadzsh-eebfabe5487484b3d1e732386989e739bd3d869e.tar.gz
zsh-eebfabe5487484b3d1e732386989e739bd3d869e.zip
- The return value of mbrtowc() is a size_t (unsigned), so don't
assign it to an int and then check for negativity, as that won't work on a system where an int is larger than a size_t. - When mbrtowc() returns -2 when given all the remaining chars in a string, set an end-of-line flag and avoid calling mbrtowc() again for any of the incomplete characters that remain in the string. - Use STOUC() when passing a char value to nicechar(). - Use "mbs" for the multi-byte state variable name (for consistency). - Be sure to reset the mbs state if mbrtowc() returns -1. - Use the new MB_INVALID and MB_INCOMPLETE defines for the size_t -1 and -2 values (respectively).
-rw-r--r--Src/prompt.c132
1 files changed, 71 insertions, 61 deletions
diff --git a/Src/prompt.c b/Src/prompt.c
index d21029a37..cf0e75adb 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -738,10 +738,10 @@ stradd(char *d)
{
#ifdef MULTIBYTE_SUPPORT
char *ums, *ups;
- int upslen;
- mbstate_t ps;
+ int upslen, eol = 0;
+ mbstate_t mbs;
- memset(&ps, 0, sizeof(ps));
+ memset(&mbs, 0, sizeof mbs);
ums = ztrdup(d);
ups = unmetafy(ums, &upslen);
@@ -752,22 +752,31 @@ stradd(char *d)
while (upslen > 0) {
wchar_t cc;
char *pc;
- int ret = mbrtowc(&cc, ups, upslen, &ps);
+ size_t cnt = eol ? MB_INVALID : mbrtowc(&cc, ups, upslen, &mbs);
- if (ret <= 0)
- {
+ switch (cnt) {
+ case MB_INCOMPLETE:
+ eol = 1;
+ /* FALL THROUGH */
+ case MB_INVALID:
/* Bad character. Take the next byte on its own. */
- pc = nicechar(*ups);
- ret = 1;
- } else {
+ pc = nicechar(STOUC(*ups));
+ cnt = 1;
+ memset(&mbs, 0, sizeof mbs);
+ break;
+ case 0:
+ cnt = 1;
+ /* FALL THROUGH */
+ default:
/* Take full wide character in one go */
pc = wcs_nicechar(cc, NULL, NULL);
+ break;
}
/* Keep output as metafied string. */
addbufspc(strlen(pc));
- upslen -= ret;
- ups += ret;
+ upslen -= cnt;
+ ups += cnt;
/* Put printed representation into the buffer */
while (*pc)
@@ -862,7 +871,7 @@ countprompt(char *str, int *wp, int *hp, int overf)
int w = 0, h = 1;
int s = 1;
#ifdef MULTIBYTE_SUPPORT
- int mbret, wcw, multi = 0;
+ int wcw, multi = 0;
char inchar;
mbstate_t mbs;
wchar_t wc;
@@ -918,24 +927,25 @@ countprompt(char *str, int *wp, int *hp, int overf)
}
#ifdef MULTIBYTE_SUPPORT
- mbret = mbrtowc(&wc, &inchar, 1, &mbs);
- if (mbret >= -1) {
- if (mbret > 0) {
- /*
- * If the character isn't printable, this returns -1.
- */
- wcw = wcwidth(wc);
- if (wcw > 0)
- w += wcw;
- }
- /*
- * else invalid character or possibly null: assume no
- * output
- */
- multi = 0;
- } else {
- /* else character is incomplete, keep looking. */
+ switch (mbrtowc(&wc, &inchar, 1, &mbs)) {
+ case MB_INCOMPLETE:
+ /* Character is incomplete -- keep looking. */
multi = 1;
+ break;
+ case MB_INVALID:
+ memset(&mbs, 0, sizeof mbs);
+ /* FALL THROUGH */
+ case 0:
+ /* Invalid character or null: assume no output. */
+ multi = 0;
+ break;
+ default:
+ /* If the character isn't printable, wcwidth() returns -1. */
+ wcw = wcwidth(wc);
+ if (wcw > 0)
+ w += wcw;
+ multi = 0;
+ break;
}
#else
w++;
@@ -1078,7 +1088,7 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar)
int remw;
#ifdef MULTIBYTE_SUPPORT
mbstate_t mbs;
- memset(&mbs, 0, sizeof(mbstate_t));
+ memset(&mbs, 0, sizeof mbs);
#endif
fulltextptr = fulltext = ptr + ntrunc;
@@ -1117,7 +1127,6 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar)
*/
char inchar;
wchar_t cc;
- int ret;
/*
* careful: string is still metafied (we
@@ -1130,20 +1139,21 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar)
else
inchar = *fulltextptr;
fulltextptr++;
- ret = mbrtowc(&cc, &inchar, 1, &mbs);
-
- if (ret != -2) {
- /* complete */
- if (ret <= 0) {
- /* assume a single-byte character */
- remw--;
- if (ret < 0) {
- /* need to reset invalid state */
- memset(&mbs, 0, sizeof(mbstate_t));
- }
- } else {
- remw -= wcwidth(cc);
- }
+ switch (mbrtowc(&cc, &inchar, 1, &mbs)) {
+ case MB_INCOMPLETE:
+ /* Incomplete multibyte character. */
+ break;
+ case MB_INVALID:
+ /* Reset invalid state. */
+ memset(&mbs, 0, sizeof mbs);
+ /* FALL THROUGH */
+ case 0:
+ /* Assume a single-byte character. */
+ remw--;
+ break;
+ default:
+ remw -= wcwidth(cc);
+ break;
}
#else
/* Single byte character */
@@ -1172,7 +1182,7 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar)
char *skiptext = ptr;
#ifdef MULTIBYTE_SUPPORT
mbstate_t mbs;
- memset(&mbs, 0, sizeof(mbstate_t));
+ memset(&mbs, 0, sizeof mbs);
#endif
while (maxwidth > 0 && *skiptext) {
@@ -1183,27 +1193,27 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar)
#ifdef MULTIBYTE_SUPPORT
char inchar;
wchar_t cc;
- int ret;
if (*skiptext == Meta)
inchar = *++skiptext ^ 32;
else
inchar = *skiptext;
skiptext++;
- ret = mbrtowc(&cc, &inchar, 1, &mbs);
-
- if (ret != -2) {
- /* complete or invalid character */
- if (ret <= 0) {
- /* assume single byte */
- maxwidth--;
- if (ret < 0) {
- /* need to reset invalid state */
- memset(&mbs, 0, sizeof(mbstate_t));
- }
- } else {
- maxwidth -= wcwidth(cc);
- }
+ switch (mbrtowc(&cc, &inchar, 1, &mbs)) {
+ case MB_INCOMPLETE:
+ /* Incomplete character. */
+ break;
+ case MB_INVALID:
+ /* Reset invalid state. */
+ memset(&mbs, 0, sizeof mbs);
+ /* FALL THROUGH */
+ case 0:
+ /* Assume a single-byte character. */
+ maxwidth--;
+ break;
+ default:
+ maxwidth -= wcwidth(cc);
+ break;
}
#else
if (*skiptext == Meta)