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:
parent
e46d08523f
commit
542797377a
4 changed files with 42 additions and 31 deletions
|
@ -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, ¨en);
|
uptr = unmetafy(ums, ¨en);
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue