summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWayne Davison <wayned@users.sourceforge.net>2006-02-18 18:39:38 +0000
committerWayne Davison <wayned@users.sourceforge.net>2006-02-18 18:39:38 +0000
commit1e2f61f11624ddc034dbe4ce3ab64a8a24d56c09 (patch)
treebe51ad4ef35e28ae8ff4b88edf2cf6c493d880cc
parent3569d06bc477f566eb261669217a0a5b40fa9fe3 (diff)
downloadzsh-1e2f61f11624ddc034dbe4ce3ab64a8a24d56c09.tar.gz
zsh-1e2f61f11624ddc034dbe4ce3ab64a8a24d56c09.zip
The code in add_match_data() that looks for invalid characters
now properly parses the string as metafied.
-rw-r--r--Src/Zle/compcore.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 80a469c15..c0a5401bc 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -2229,8 +2229,9 @@ add_match_data(int alt, char *str, char *orig, Cline line,
{
#ifdef MULTIBYTE_SUPPORT
mbstate_t mbs;
- char *t, *f, *new_str = NULL;
- int fl, eol = 0;
+ char curchar, *t, *f, *fs, *fe, *new_str = NULL;
+ size_t cnt;
+ wchar_t wc;
#endif
Cmatch cm;
Aminfo ai = (alt ? fainfo : ainfo);
@@ -2456,12 +2457,14 @@ add_match_data(int alt, char *str, char *orig, Cline line,
/* If "str" contains a character that won't convert into a wide
* character, change it into a $'\123' sequence. */
memset(&mbs, '\0', sizeof mbs);
- for (t = f = str, fl = stl; fl > 0; ) {
- wchar_t wc;
- size_t cnt = eol ? MB_INVALID : mbrtowc(&wc, f, fl, &mbs);
+ for (t = f = fs = str, fe = f + stl; fs < fe; ) {
+ if ((curchar = *f++) == Meta)
+ curchar = *f++ ^ 32;
+ cnt = mbrtowc(&wc, &curchar, 1, &mbs);
switch (cnt) {
case MB_INCOMPLETE:
- eol = 1;
+ if (f < fe)
+ continue;
/* FALL THROUGH */
case MB_INVALID:
/* Get mbs out of its undefined state. */
@@ -2472,27 +2475,25 @@ add_match_data(int alt, char *str, char *orig, Cline line,
memcpy(new_str, str, t - str);
t = new_str + (t - str);
}
- *t++ = '$';
- *t++ = '\'';
- *t++ = '\\';
- *t++ = '0' + ((STOUC(*f) >> 6) & 7);
- *t++ = '0' + ((STOUC(*f) >> 3) & 7);
- *t++ = '0' + (STOUC(*f) & 7);
- *t++ = '\'';
- f++;
- fl--;
+ /* Backup and output just the first bad char unless we
+ * got an MB_INCOMPLETE at the end of the string. */
+ f = fs;
+ do {
+ if ((curchar = *f++) == Meta)
+ curchar = *f++ ^ 32;
+ *t++ = '$';
+ *t++ = '\'';
+ *t++ = '\\';
+ *t++ = '0' + ((STOUC(curchar) >> 6) & 7);
+ *t++ = '0' + ((STOUC(curchar) >> 3) & 7);
+ *t++ = '0' + (STOUC(curchar) & 7);
+ *t++ = '\'';
+ } while (cnt == MB_INCOMPLETE && f < fe);
+ fs = f;
break;
- case 0:
- /* Converting '\0' returns 0, but a '\0' is a real
- * character for us, so we should consume 1 byte
- * (certainly true for Unicode and unlikely to be false
- * in any non-pathological multibyte representation). */
- cnt = 1;
- /* FALL THROUGH */
default:
- fl -= cnt;
- while (cnt--)
- *t++ = *f++;
+ while (fs < f)
+ *t++ = *fs++;
break;
}
}