From 542797377aabd9af067909fd14af08b1081b250c Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Thu, 12 Jan 2006 00:51:50 +0000 Subject: - 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 "mbs" for the multi-byte state variable name (for consistency). - Use the new MB_INVALID and MB_INCOMPLETE defines for the size_t -1 and -2 values (respectively). --- Src/Zle/complist.c | 20 +++++++++++--------- Src/Zle/compmatch.c | 12 ++++++------ Src/Zle/zle_main.c | 14 +++++++------- Src/Zle/zle_refresh.c | 27 ++++++++++++++++++--------- 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index 5afd78115..9e633e64f 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -572,14 +572,14 @@ clnicezputs(Listcols colors, char *s, int ml) * umlen is the full length of the unmetafied string * width is the full printing width of a prettified character, * including both ASCII prettification and the wide character itself. - * ps is the shift state of the conversion to wide characters. + * mbs is the shift state of the conversion to wide characters. */ char *ums, *uptr, *sptr, *wptr; - int umleft, umlen; + int umleft, umlen, eol = 0; size_t width; - mbstate_t ps; + mbstate_t mbs; - memset(&ps, 0, sizeof(ps)); + memset(&mbs, 0, sizeof mbs); ums = ztrdup(s); untokenize(ums); uptr = unmetafy(ums, ¨en); @@ -589,11 +589,13 @@ clnicezputs(Listcols colors, char *s, int ml) initiscol(colors); while (umleft > 0) { - size_t cnt = mbrtowc(&cc, uptr, umleft, &ps); + size_t cnt = eol ? MB_INVALID : mbrtowc(&cc, uptr, umleft, &mbs); switch (cnt) { - case (size_t)-2: - case (size_t)-1: + case MB_INCOMPLETE: + eol = 1; + /* FALL THROUGH */ + case MB_INVALID: /* This handles byte values that aren't valid wide-character * sequences. */ sptr = nicechar(STOUC(*uptr)); @@ -601,8 +603,8 @@ clnicezputs(Listcols colors, char *s, int ml) width = strlen(sptr); wptr = sptr + width; cnt = 1; - /* Get ps out of its undefined state. */ - memset(&ps, 0, sizeof ps); + /* Get mbs out of its undefined state. */ + memset(&mbs, 0, sizeof mbs); break; case 0: /* This handles a '\0' in the input (which is a real char diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c index ec856041f..26b76ec84 100644 --- a/Src/Zle/compmatch.c +++ b/Src/Zle/compmatch.c @@ -1587,7 +1587,7 @@ sub_match(Cmdata md, char *str, int len, int sfx) #ifdef MULTIBYTE_SUPPORT int fulllen = len; char *fullstr = str; - mbstate_t ps; + mbstate_t mbs; #endif if (sfx) { @@ -1629,7 +1629,7 @@ sub_match(Cmdata md, char *str, int len, int sfx) */ q = sfx ? str - l : str + l; if (q != fullstr) { - memset(&ps, 0, sizeof(ps)); + memset(&mbs, 0, sizeof mbs); /* * Otherwise read characters from the start of the original * string until we reach or pass the match point. This @@ -1645,7 +1645,7 @@ sub_match(Cmdata md, char *str, int len, int sfx) * ret must, in fact, be set by the current logic, * but gcc doesn't realise (at least some versions don't). */ - size_t cnt = (size_t)-1; + size_t cnt = MB_INVALID; int diff; char *p2; @@ -1655,12 +1655,12 @@ sub_match(Cmdata md, char *str, int len, int sfx) */ for (p2 = p; p2 < fullstr + fulllen; p2++) { char curchar = (*p2 == Meta) ? (*++p2 ^ 32) : *p2; - cnt = mbrtowc(&wc, &curchar, 1, &ps); + cnt = mbrtowc(&wc, &curchar, 1, &mbs); /* Continue while character is incomplete. */ - if (cnt != (size_t)-2) + if (cnt != MB_INCOMPLETE) break; } - if (cnt == (size_t)-1 || cnt == (size_t)-2) { + if (cnt == MB_INVALID || cnt == MB_INCOMPLETE) { /* not a valid character, give up test */ break; } diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 840abe4b7..a4ea10339 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -761,7 +761,7 @@ getrestchar(int inchar) char c = inchar; wchar_t outchar; int timeout; - static mbstate_t ps; + static mbstate_t mbs; /* * We are guaranteed to set a valid wide last character, @@ -772,7 +772,7 @@ getrestchar(int inchar) if (inchar == EOF) { /* End of input, so reset the shift state. */ - memset(&ps, 0, sizeof(ps)); + memset(&mbs, 0, sizeof mbs); return lastchar_wide = WEOF; } @@ -781,15 +781,15 @@ getrestchar(int inchar) * any other character. */ while (1) { - size_t cnt = mbrtowc(&outchar, &c, 1, &ps); - if (cnt == (size_t)-1) { + size_t cnt = mbrtowc(&outchar, &c, 1, &mbs); + if (cnt == MB_INVALID) { /* * Invalid input. Hmm, what's the right thing to do here? */ - memset(&ps, 0, sizeof(ps)); + memset(&mbs, 0, sizeof mbs); return lastchar_wide = WEOF; } - if (cnt != (size_t)-2) + if (cnt != MB_INCOMPLETE) break; /* @@ -802,7 +802,7 @@ getrestchar(int inchar) /* getbyte deliberately resets lastchar_wide_valid */ lastchar_wide_valid = 1; if (inchar == EOF) { - memset(&ps, 0, sizeof(ps)); + memset(&mbs, 0, sizeof mbs); if (timeout) { /* diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index dad4960cb..a1a2ebb8d 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -1446,6 +1446,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) refreshop = *obuf; /* pointer to old video buffer */ int t0, /* tmp */ vsiz, /* size of new video buffer */ + eol = 0, /* has mbrtowc() returned -2? */ nvcs = 0; /* new video cursor column */ #ifdef MULTIBYTE_SUPPORT /* @@ -1455,7 +1456,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) ZLE_STRING_T lpwbuf, lpwp; char *lpptr, /* pointer into multibyte lprompt */ *lpend; /* end of multibyte lprompt */ - mbstate_t ps; /* shift state */ + mbstate_t mbs; /* shift state */ #endif nlnct = 1; @@ -1490,18 +1491,26 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) lpwp = lpwbuf = (ZLE_STRING_T)zalloc((lpend - lpromptbuf) * sizeof(*lpwbuf)); /* Reset shift state, maybe. */ - memset(&ps, '\0', sizeof(ps)); + memset(&mbs, '\0', sizeof mbs); for (lpptr = lpromptbuf; lpptr < lpend; ) { - size_t cnt = mbrtowc(lpwp, lpptr, lpend - lpptr, &ps); - if (cnt != 0 && cnt != (size_t)-1 && cnt != (size_t)-2) { - /* successfully converted */ - lpptr += cnt; - lpwp++; - } else { + size_t cnt = mbrtowc(lpwp, lpptr, lpend - lpptr, &mbs); + switch (cnt) { + case MB_INCOMPLETE: + eol = 1; + /* FALL THROUGH */ + case MB_INVALID: + memset(&mbs, '\0', sizeof mbs); + /* FALL THROUGH */ + case 0: /* dunno, try to recover */ lpptr++; *lpwp++ = ZWC('?'); - memset(&ps, '\0', sizeof(ps)); + break; + default: + /* successfully converted */ + lpptr += cnt; + lpwp++; + break; } } if (lpwp - lpwbuf < lpromptw) { -- cgit 1.4.1