From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15592 invoked by alias); 9 Jun 2014 09:26:46 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 32756 Received: (qmail 28640 invoked from network); 9 Jun 2014 09:26:31 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 Content-Type: multipart/mixed; boundary="Apple-Mail=_5250FA06-AAC5-4C65-80D7-6C5E3BB47CE8" Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.2\)) Subject: Weird completion bug in Src/Zle/compmatch.c#bld_line From: "nicolas.canceill" In-Reply-To: <5902E7DB-F4FD-4486-BE0D-14BAA165FCE9@kba.biglobe.ne.jp> Date: Mon, 9 Jun 2014 11:18:26 +0200 Cc: Bart Schaefer , "Jun T." Message-Id: <1A1C7709-6FDE-4C00-A366-C6F5C6A4FACA@laposte.net> References: <33086926-C7D7-4D33-AF86-4B0D48977555@laposte.net> <140607105445.ZM24783@torch.brasslantern.com> <140607123006.ZM25086@torch.brasslantern.com> <35EC1DF1-5D60-42CA-93FB-A6400E4308CF@laposte.net> <140607140205.ZM26027@torch.brasslantern.com> <24D729FF-77D8-4F38-848B-86920FE1FD11@laposte.net> <5902E7DB-F4FD-4486-BE0D-14BAA165FCE9@kba.biglobe.ne.jp> To: zsh-workers@zsh.org X-Mailer: Apple Mail (2.1878.2) --Apple-Mail=_5250FA06-AAC5-4C65-80D7-6C5E3BB47CE8 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=windows-1252 Hi zsh-workers, TL;DR Using openlog(...) (from syslog.h) at the beginning and closelog() = at the end of Src/Zle/compmatch.c#bld_line(...) solves a weird = completion bug. *** I feel a little bit like Alice =97 although this message is not sent to = Bob. As you can read from the threads [1,2], I was looking for the White = Rabbit, and Bart Schaefer helped me track him down to = Src/Zle/compmatch.c. And the rabbit hole runs deep: 2900 lines! So I was = gazing through the looking glass of Zsh C routines, and I was wondering = how to log stuff from over there. Unfortunately, no one can believe what the fix is: you have to see it = for yourself. Jun kindly suggested I should use a file descriptor to = another TTY, and Bart mentioned dputs. But I first tried with syslog(3), = and I started tumbling down the rabbit hole. syslog(3) actually solved the bug. No kidding. You take the red pill, we = stay in Wonderland, and I will show you. *** Since it initially got posted on zsh-users, let me summarize the bug for = you. It originates from that case-insensitive substring-matching = completion style I heard about from the Cheshire cat: zstyle ':completion:*' matcher-list 'm:{a-zA-Z}=3D{A-Za-z}' 'l:|=3D* = r:|=3D*' The bug occurs when a completion leads to multiple completion choices, = under the following conditions: * completion choices are all the same length; * completion choices share a common suffix; * that suffix is at least half of the length but not the full length; * in each choice, the first and the n-th character of the suffix are = both letters, where n is the length of the prefix; * in each choice, the character just before the common suffix is a digit = (or some other non-letter character, like an underscore, or the Queen of = Hearts), and that character is different for each choice. The Hatter told me that the above list of conditions looked like = "quantum mechanics". I myself agree with the Duchess: "he only does it = to annoy / because he knows it teases". Under the above conditions, the bug happens when completing after a = substring prefixing the common suffix (i.e. completing after "a" or "al" = or ... or "alice", when the common suffix is "alice"). Expected behavior: the suffix gets completed. The Duchess and her baby = sneeze. Actual behavior: the suffix gets completed, but a letter is inserted = before the suffix. This letter is the n-th character of the suffix, in = inverted case. The baby changes into a pig. Example 1: in a directory containing two files "1abc" and "2abc", = completing after ": a" will expand it to "abc" and then add an extra = "A", so the command line will look like ": Aabc". Example 2: on a table with a cake saying "__eat_me_please" and a bottle = saying "drink%me_please", completing after ": me_p" will expand it to = "me_please" and then add an extra "E", so the command line will look = like ": Eme_please". *** Now that you know the bug, on to what I have tried so far. I have been = working on version 5.0.2, where the bld_line function is in = Src/Zle/compmatch.c at lines 1669-1920. By the way, debugging a = 350-line-long function fells like swimming in a pool made of my own = tears. So first, I started by #include-ing and logging parameters in = the first lines of the bld_line function, like so: openlog("zsh",LOG_PID|LOG_CONS,LOG_USER); syslog(LOG_WARNING,"lpat: %s",lpat->u.str); closelog(); Compiles fine, logs fine. Great. But then I think "hey, in a minute I am = gonna want to log stuff all over the place, let me close the log at the = end of the function instead". So I move the "closelog();" call to the end of the function, and I = duplicate it because the bld_line function actually has four return = statements. And, like that: poof... he's gone! =97 I mean that the bug = disappeared just because I closed the log at the end of the function!!! Moreover, the "syslog(...);" call is irrelevant! Simply calling = "openlog" at the beginning of the routine, and "closelog" before each = return statement, fixes the bug. WAT? So I included a patch, you can = show it to you friends and have a good laugh. --Apple-Mail=_5250FA06-AAC5-4C65-80D7-6C5E3BB47CE8 Content-Disposition: attachment; filename=zsh-5.0.2-compmatch.patch Content-Type: application/octet-stream; name="zsh-5.0.2-compmatch.patch" Content-Transfer-Encoding: 7bit diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c index 4cd3b9f..27c0e6c 100644 --- a/Src/Zle/compmatch.c +++ b/Src/Zle/compmatch.c @@ -29,6 +29,7 @@ #include "complete.mdh" #include "compmatch.pro" +#include /* * This compares two cpattern lists and returns non-zero if they are @@ -1679,6 +1680,8 @@ bld_line(Cmatcher mp, ZLE_STRING_T line, char *mword, char *word, VARARR(convchar_t, wordchars, wlen); VARARR(struct cpattern, genpatarr, mp->llen); + openlog("zsh",LOG_PID|LOG_CONS,LOG_USER); + /* * We may need to start the "word" array from the end. This * is much easier if we convert it to an array of (possibly wide) @@ -1741,6 +1744,7 @@ bld_line(Cmatcher mp, ZLE_STRING_T line, char *mword, char *word, /* * No equivalent. No possible match; give up. */ + closelog(); return 0; } /* @@ -1909,13 +1913,16 @@ bld_line(Cmatcher mp, ZLE_STRING_T line, char *mword, char *word, } } if (!ms) + closelog(); return 0; /* Didn't match, give up */ } } if (!llen) { /* Unmatched portion in the line built, return matched length. */ + closelog(); return rl; } + closelog(); return 0; } --Apple-Mail=_5250FA06-AAC5-4C65-80D7-6C5E3BB47CE8 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=windows-1252 Either my gcc is making fun of me, or... it finally happened, happened, = I'm slightly maaaaaaad. What is going on? I thought I did not drink any = of his special tea... his specialty... Why is a raven like a writing = desk? *** Sorry about the Carroll-esque tone, I could not help it =97 maybe I am = indeed slightly mad. If you know why syslog(3) fixes the bug, or if you = have any insight about what is happening here, I will be happy to hear = from you. Cheers guys. Nicolas Canceill [1] http://www.zsh.org/mla/users/2014/threads.html#0061 [2] http://www.zsh.org/mla/workers/2014/threads.html#00534 Le 8 juin 2014 =E0 17:47, Jun T. a =E9crit = : > 2014/06/08 19:25, nicolas.canceill = wrote: >>=20 >> ... so I prefer to log a bunch of stuff from within the C functions. >=20 > How about writing to the tty of another window? >=20 > Open a terminal window, and use the 'tty' command to show the device = name > of the tty of this window: >=20 > $ tty > /dev/ttys002 >=20 > Then open another terminal window, edit the source code to add lines = like >=20 > FILE *mylog =3D fopen("/dev/ttys002", "w"); > ... > fprintf(mylog, "log/debug info....\n"); >=20 > and build/run the program. --Apple-Mail=_5250FA06-AAC5-4C65-80D7-6C5E3BB47CE8--