From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10632 invoked by alias); 26 Mar 2015 20:29:04 -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: 34784 Received: (qmail 18371 invoked from network); 26 Mar 2015 20:28:59 -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,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-Originating-IP: [80.3.228.158] X-Spam: 0 X-Authority: v=2.1 cv=VLdTnr/X c=1 sm=1 tr=0 a=P+FLVI8RzFchTbbqTxIDRw==:117 a=P+FLVI8RzFchTbbqTxIDRw==:17 a=kj9zAlcOel0A:10 a=NLZqzBF-AAAA:8 a=niwjlYrelrM4ZiWJjBsA:9 a=cjSHDFSjw5qX35ul:21 a=I9eUp4_Z4VynY2jo:21 a=CjuIK1q_8ugA:10 Date: Thu, 26 Mar 2015 20:23:21 +0000 From: Peter Stephenson To: Zsh hackers list Subject: PATCH: ancient history bug Message-ID: <20150326202321.3f7fc86f@ntlworld.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Adding some further history tests (which I'll get back to tomorrow), I found this bug. It's probably been there since I factored out the input code from the history code --- predating the CVS archive. So !-history can't be *that* popular: % print This is a mystery This is a mystery % print !:3-$ print a mystery a mystery % print !:1-$ print a a Oops: the last word has gone. Now you see it, now you This is more fallout from the fact that aliases and history expansions are handled in similar ways. When ungetting a character we need to take care when going back up the expansion stack to discriminate --- if we hit the end of the word in an alias, we'll think we don't need to mark it as a word for the history. pws diff --git a/Src/input.c b/Src/input.c index 30970a0..4a5bf89 100644 --- a/Src/input.c +++ b/Src/input.c @@ -56,8 +56,9 @@ * inpop(), which effectively flushes any unread input as well as restoring * the previous input state. * - * The internal flag INP_ALCONT shows that the stack element was pushed - * by an alias expansion; it should not be needed elsewhere. + * The internal flags INP_ALCONT and INP_HISTCONT show that the stack + * element was pushed by an alias or history expansion; they should not + * be needed elsewhere. * * The global variable inalmore is set to indicate aliases should * continue to be expanded because the last alias expansion ended @@ -446,7 +447,8 @@ inungetc(int c) * we may need to restore an alias popped from the stack. * Note this may be a dummy (history expansion) entry. */ - if (inbufptr == inbufpush && inbufflags & INP_ALCONT) { + if (inbufptr == inbufpush && + (inbufflags & (INP_ALCONT|INP_HISTCONT))) { /* * Go back up the stack over all entries which were alias * expansions and were pushed with nothing remaining to read. @@ -455,8 +457,12 @@ inungetc(int c) if (instacktop->alias) instacktop->alias->inuse = 1; instacktop++; - } while ((instacktop->flags & INP_ALCONT) && !instacktop->bufleft); - inbufflags = INP_CONT|INP_ALIAS; + } while ((instacktop->flags & (INP_ALCONT|INP_HISTCONT)) + && !instacktop->bufleft); + if (inbufflags & INP_HISTCONT) + inbufflags = INP_CONT|INP_ALIAS|INP_HIST; + else + inbufflags = INP_CONT|INP_ALIAS; inbufleft = 0; inbuf = inbufptr = ""; } @@ -522,7 +528,7 @@ inpush(char *str, int flags, Alias inalias) instacktop->bufptr = inbufptr; instacktop->bufleft = inbufleft; instacktop->bufct = inbufct; - inbufflags &= ~INP_ALCONT; + inbufflags &= ~(INP_ALCONT|INP_HISTCONT); if (flags & (INP_ALIAS|INP_HIST)) { /* * Text is expansion for history or alias, so continue @@ -531,7 +537,10 @@ inpush(char *str, int flags, Alias inalias) * and mark alias as in use. */ flags |= INP_CONT|INP_ALIAS; - instacktop->flags = inbufflags | INP_ALCONT; + if (flags & INP_HIST) + instacktop->flags = inbufflags | INP_HISTCONT; + else + instacktop->flags = inbufflags | INP_ALCONT; if ((instacktop->alias = inalias)) inalias->inuse = 1; } else { @@ -570,7 +579,7 @@ static void inpoptop(void) { if (!lexstop) { - inbufflags &= ~INP_ALCONT; + inbufflags &= ~(INP_ALCONT|INP_HISTCONT); while (inbufptr > inbuf) { inbufptr--; inbufct++; @@ -598,7 +607,7 @@ inpoptop(void) inbufct = instacktop->bufct; inbufflags = instacktop->flags; - if (!(inbufflags & INP_ALCONT)) + if (!(inbufflags & (INP_ALCONT|INP_HISTCONT))) return; if (instacktop->alias) { diff --git a/Src/zsh.h b/Src/zsh.h index 403e8d3..486ad80 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -411,8 +411,9 @@ enum { #define INP_HIST (1<<2) /* expanding history */ #define INP_CONT (1<<3) /* continue onto previously stacked input */ #define INP_ALCONT (1<<4) /* stack is continued from alias expn. */ -#define INP_LINENO (1<<5) /* update line number */ -#define INP_APPEND (1<<6) /* Append new lines to allow backup */ +#define INP_HISTCONT (1<<5) /* stack is continued from history expn. */ +#define INP_LINENO (1<<6) /* update line number */ +#define INP_APPEND (1<<7) /* Append new lines to allow backup */ /* Flags for metafy */ #define META_REALLOC 0