From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: zsh-workers@sunsite.dk (Zsh hackers list)
Subject: PATCH: pfxlen()
Date: Tue, 01 Nov 2005 22:29:05 +0000 [thread overview]
Message-ID: <200511012229.jA1MT5gU012756@pwslaptop.csr.com> (raw)
This should fix pfxlen(), which is used in a few places in zle to find
common prefixes, so that it doesn't stop in the middle of a multibyte
character. It's actually quite hard to exercise the function, so it's
not particularly well tested.
As it's likely to stay using multibyte characters while wpfxlen() uses
wide characters, I've removed Andrey's comments about merging the two.
Index: Src/Zle/zle_refresh.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_refresh.c,v
retrieving revision 1.40
diff -u -r1.40 zle_refresh.c
--- Src/Zle/zle_refresh.c 1 Nov 2005 04:02:02 -0000 1.40
+++ Src/Zle/zle_refresh.c 1 Nov 2005 22:27:08 -0000
@@ -934,7 +934,6 @@
#define tc_upcurs(X) (void) tcmultout(TCUP, TCMULTUP, (X))
#define tc_leftcurs(X) (void) tcmultout(TCLEFT, TCMULTLEFT, (X))
-/* TODO remove it when pfxlen is fixed */
static int
wpfxlen(REFRESH_STRING s, REFRESH_STRING t)
{
@@ -1143,7 +1142,6 @@
makes it cheaper to delete intermediate characters
eg. oldline: hifoobar \ hopefully cheaper here to delete two
newline: foobar / characters, then we have six matches */
- /* TODO replace wpfxlen back with pfxlen when the latter is fixed */
if (tccan(TCDEL)) {
for (i = 1; *(ol + i); i++)
if (tcdelcost(i) < wpfxlen(ol + i, nl)) {
Index: Src/Zle/zle_tricky.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_tricky.c,v
retrieving revision 1.59
diff -u -r1.59 zle_tricky.c
--- Src/Zle/zle_tricky.c 1 Nov 2005 03:26:56 -0000 1.59
+++ Src/Zle/zle_tricky.c 1 Nov 2005 22:27:09 -0000
@@ -1899,7 +1899,12 @@
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 @@
{
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. */
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page still at http://www.pwstephenson.fsnet.co.uk/
reply other threads:[~2005-11-01 22:29 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200511012229.jA1MT5gU012756@pwslaptop.csr.com \
--to=p.w.stephenson@ntlworld.com \
--cc=zsh-workers@sunsite.dk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).