1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-29 19:00:57 +02:00

- 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).
This commit is contained in:
Wayne Davison 2006-01-12 00:51:50 +00:00
parent e46d08523f
commit 542797377a
4 changed files with 42 additions and 31 deletions

View file

@ -572,14 +572,14 @@ clnicezputs(Listcols colors, char *s, int ml)
* umlen is the full length of the unmetafied string * umlen is the full length of the unmetafied string
* width is the full printing width of a prettified character, * width is the full printing width of a prettified character,
* including both ASCII prettification and the wide character itself. * 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; char *ums, *uptr, *sptr, *wptr;
int umleft, umlen; int umleft, umlen, eol = 0;
size_t width; size_t width;
mbstate_t ps; mbstate_t mbs;
memset(&ps, 0, sizeof(ps)); memset(&mbs, 0, sizeof mbs);
ums = ztrdup(s); ums = ztrdup(s);
untokenize(ums); untokenize(ums);
uptr = unmetafy(ums, &umlen); uptr = unmetafy(ums, &umlen);
@ -589,11 +589,13 @@ clnicezputs(Listcols colors, char *s, int ml)
initiscol(colors); initiscol(colors);
while (umleft > 0) { while (umleft > 0) {
size_t cnt = mbrtowc(&cc, uptr, umleft, &ps); size_t cnt = eol ? MB_INVALID : mbrtowc(&cc, uptr, umleft, &mbs);
switch (cnt) { switch (cnt) {
case (size_t)-2: case MB_INCOMPLETE:
case (size_t)-1: eol = 1;
/* FALL THROUGH */
case MB_INVALID:
/* This handles byte values that aren't valid wide-character /* This handles byte values that aren't valid wide-character
* sequences. */ * sequences. */
sptr = nicechar(STOUC(*uptr)); sptr = nicechar(STOUC(*uptr));
@ -601,8 +603,8 @@ clnicezputs(Listcols colors, char *s, int ml)
width = strlen(sptr); width = strlen(sptr);
wptr = sptr + width; wptr = sptr + width;
cnt = 1; cnt = 1;
/* Get ps out of its undefined state. */ /* Get mbs out of its undefined state. */
memset(&ps, 0, sizeof ps); memset(&mbs, 0, sizeof mbs);
break; break;
case 0: case 0:
/* This handles a '\0' in the input (which is a real char /* This handles a '\0' in the input (which is a real char

View file

@ -1587,7 +1587,7 @@ sub_match(Cmdata md, char *str, int len, int sfx)
#ifdef MULTIBYTE_SUPPORT #ifdef MULTIBYTE_SUPPORT
int fulllen = len; int fulllen = len;
char *fullstr = str; char *fullstr = str;
mbstate_t ps; mbstate_t mbs;
#endif #endif
if (sfx) { if (sfx) {
@ -1629,7 +1629,7 @@ sub_match(Cmdata md, char *str, int len, int sfx)
*/ */
q = sfx ? str - l : str + l; q = sfx ? str - l : str + l;
if (q != fullstr) { if (q != fullstr) {
memset(&ps, 0, sizeof(ps)); memset(&mbs, 0, sizeof mbs);
/* /*
* Otherwise read characters from the start of the original * Otherwise read characters from the start of the original
* string until we reach or pass the match point. This * 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, * ret must, in fact, be set by the current logic,
* but gcc doesn't realise (at least some versions don't). * but gcc doesn't realise (at least some versions don't).
*/ */
size_t cnt = (size_t)-1; size_t cnt = MB_INVALID;
int diff; int diff;
char *p2; char *p2;
@ -1655,12 +1655,12 @@ sub_match(Cmdata md, char *str, int len, int sfx)
*/ */
for (p2 = p; p2 < fullstr + fulllen; p2++) { for (p2 = p; p2 < fullstr + fulllen; p2++) {
char curchar = (*p2 == Meta) ? (*++p2 ^ 32) : *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. */ /* Continue while character is incomplete. */
if (cnt != (size_t)-2) if (cnt != MB_INCOMPLETE)
break; break;
} }
if (cnt == (size_t)-1 || cnt == (size_t)-2) { if (cnt == MB_INVALID || cnt == MB_INCOMPLETE) {
/* not a valid character, give up test */ /* not a valid character, give up test */
break; break;
} }

View file

@ -761,7 +761,7 @@ getrestchar(int inchar)
char c = inchar; char c = inchar;
wchar_t outchar; wchar_t outchar;
int timeout; int timeout;
static mbstate_t ps; static mbstate_t mbs;
/* /*
* We are guaranteed to set a valid wide last character, * We are guaranteed to set a valid wide last character,
@ -772,7 +772,7 @@ getrestchar(int inchar)
if (inchar == EOF) { if (inchar == EOF) {
/* End of input, so reset the shift state. */ /* End of input, so reset the shift state. */
memset(&ps, 0, sizeof(ps)); memset(&mbs, 0, sizeof mbs);
return lastchar_wide = WEOF; return lastchar_wide = WEOF;
} }
@ -781,15 +781,15 @@ getrestchar(int inchar)
* any other character. * any other character.
*/ */
while (1) { while (1) {
size_t cnt = mbrtowc(&outchar, &c, 1, &ps); size_t cnt = mbrtowc(&outchar, &c, 1, &mbs);
if (cnt == (size_t)-1) { if (cnt == MB_INVALID) {
/* /*
* Invalid input. Hmm, what's the right thing to do here? * 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; return lastchar_wide = WEOF;
} }
if (cnt != (size_t)-2) if (cnt != MB_INCOMPLETE)
break; break;
/* /*
@ -802,7 +802,7 @@ getrestchar(int inchar)
/* getbyte deliberately resets lastchar_wide_valid */ /* getbyte deliberately resets lastchar_wide_valid */
lastchar_wide_valid = 1; lastchar_wide_valid = 1;
if (inchar == EOF) { if (inchar == EOF) {
memset(&ps, 0, sizeof(ps)); memset(&mbs, 0, sizeof mbs);
if (timeout) if (timeout)
{ {
/* /*

View file

@ -1446,6 +1446,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
refreshop = *obuf; /* pointer to old video buffer */ refreshop = *obuf; /* pointer to old video buffer */
int t0, /* tmp */ int t0, /* tmp */
vsiz, /* size of new video buffer */ vsiz, /* size of new video buffer */
eol = 0, /* has mbrtowc() returned -2? */
nvcs = 0; /* new video cursor column */ nvcs = 0; /* new video cursor column */
#ifdef MULTIBYTE_SUPPORT #ifdef MULTIBYTE_SUPPORT
/* /*
@ -1455,7 +1456,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
ZLE_STRING_T lpwbuf, lpwp; ZLE_STRING_T lpwbuf, lpwp;
char *lpptr, /* pointer into multibyte lprompt */ char *lpptr, /* pointer into multibyte lprompt */
*lpend; /* end of multibyte lprompt */ *lpend; /* end of multibyte lprompt */
mbstate_t ps; /* shift state */ mbstate_t mbs; /* shift state */
#endif #endif
nlnct = 1; nlnct = 1;
@ -1490,18 +1491,26 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
lpwp = lpwbuf = (ZLE_STRING_T)zalloc((lpend - lpromptbuf) lpwp = lpwbuf = (ZLE_STRING_T)zalloc((lpend - lpromptbuf)
* sizeof(*lpwbuf)); * sizeof(*lpwbuf));
/* Reset shift state, maybe. */ /* Reset shift state, maybe. */
memset(&ps, '\0', sizeof(ps)); memset(&mbs, '\0', sizeof mbs);
for (lpptr = lpromptbuf; lpptr < lpend; ) { for (lpptr = lpromptbuf; lpptr < lpend; ) {
size_t cnt = mbrtowc(lpwp, lpptr, lpend - lpptr, &ps); size_t cnt = mbrtowc(lpwp, lpptr, lpend - lpptr, &mbs);
if (cnt != 0 && cnt != (size_t)-1 && cnt != (size_t)-2) { switch (cnt) {
/* successfully converted */ case MB_INCOMPLETE:
lpptr += cnt; eol = 1;
lpwp++; /* FALL THROUGH */
} else { case MB_INVALID:
memset(&mbs, '\0', sizeof mbs);
/* FALL THROUGH */
case 0:
/* dunno, try to recover */ /* dunno, try to recover */
lpptr++; lpptr++;
*lpwp++ = ZWC('?'); *lpwp++ = ZWC('?');
memset(&ps, '\0', sizeof(ps)); break;
default:
/* successfully converted */
lpptr += cnt;
lpwp++;
break;
} }
} }
if (lpwp - lpwbuf < lpromptw) { if (lpwp - lpwbuf < lpromptw) {