about summary refs log tree commit diff
path: root/Src/Zle/zle_tricky.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2005-11-01 23:10:17 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2005-11-01 23:10:17 +0000
commit8a9c9d80783576918f6c665fdc6751add19aa1f3 (patch)
tree0a8ecca0d1a921143bafa70a8701d4290980fb51 /Src/Zle/zle_tricky.c
parent2b281e741cda86f0e7539214235139f372764696 (diff)
downloadzsh-8a9c9d80783576918f6c665fdc6751add19aa1f3.tar.gz
zsh-8a9c9d80783576918f6c665fdc6751add19aa1f3.tar.xz
zsh-8a9c9d80783576918f6c665fdc6751add19aa1f3.zip
21971: multibyte version of pfxlen()
Diffstat (limited to 'Src/Zle/zle_tricky.c')
-rw-r--r--Src/Zle/zle_tricky.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 57a465082..9985dd901 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -1899,7 +1899,12 @@ docompletion(char *s, int lst, int incmd)
     return runhookdef(COMPLETEHOOK, (void *) &dat);
 }
 
-/* Return the length of the common prefix of s and t. */
+/*
+ * Return the length of the common prefix of s and t.
+ * s and t are both metafied; the length returned is a raw byte count
+ * into both strings, excluding any common bytes that form less than
+ * a complete wide character.
+ */
 
 /**/
 mod_export int
@@ -1907,9 +1912,46 @@ pfxlen(char *s, char *t)
 {
     int i = 0;
 
+#ifdef MULTIBYTE_SUPPORT
+    wchar_t wc;
+    mbstate_t ps;
+    int ret, lasti = 0;
+    char inc;
+
+    memset(&ps, 0, sizeof(mbstate_t));
+    while (*s) {
+	if (*s == Meta) {
+	    if (*t != Meta || t[1] != s[1])
+		break;
+	    inc = s[1] ^ 32;
+	    i += 2;
+	    s += 2;
+	    t += 2;
+	} else {
+	    if (*s != *t)
+		break;
+	    inc = *s;
+	    i++;
+	    s++;
+	    t++;
+	}
+
+	ret = mbrtowc(&wc, &inc, 1, &ps);
+	if (ret == -1) {
+	    /* error */
+	    break;
+	} else if (ret >= 0) {
+	    /* successfully found complete character, record position */
+	    lasti = i;
+	}
+	/* Otherwise, not found a complete character: keep trying. */
+    }
+    return lasti;
+#else
     while (*s && *s == *t)
 	s++, t++, i++;
     return i;
+#endif
 }
 
 /* Return the length of the common suffix of s and t. */