From: Bart Schaefer <schaefer@brasslantern.com>
To: zsh-workers@zsh.org
Subject: Re: Inconsistent history expansion of characters adjacent to histchar
Date: Mon, 07 Oct 2013 19:56:12 -0700 [thread overview]
Message-ID: <131007195612.ZM1029@torch.brasslantern.com> (raw)
In-Reply-To: <CANWLQWuM4CBXOmLkVpFN4PO3cLj72qQYbbbGZKxoAqdBwz05kw@mail.gmail.com>
On Mon, Oct 7, 2013 at 8:55 AM, Hauke Petersen <hkptrsn@gmail.com> wrote:
> It does not immediately make sense to me why a single `!' would be
> interpreted as a double `!!' before a `;' and tried, unsuccessfully,
> to find an explanation.
Bluntly, it's because that history documentation is lying to you. The
correct bit is the first sentence here:
> Event Designators
> ! Start a history expansion, except when followed by a blank, new-line,
> `=' or `('. If followed immediately by a word designator, this forms a
> history reference with no event designator.
Semicolon is not one of the things that prevents a "!" from starting
a history expansion, so everything from there forward behaves like a
history reference with no event.
This bug appears to have been around for longer than we've been keeping
source control copies of the shell. For some reason ';' is called out
in histsubchar() along with things that begin (or end) event or word
designators. The same is true of any kind of quotes, e.g.:
print !`echo foo`
print !!`echo foo`
are equivalent; "!}" also has the same problem though it usually causes
a parse error.
I think the intent is that those characters only end a history reference
after at least one other character [not in that set] has been read, but
that's not the way the loop is written, and it doesn't account for other
characters that can't be word designators, as seen here:
> there is no previous command starting with ';'. Like otherwise
> similar `&':
>
> % print !& print foo
> zsh: event not found: &
Same happens with "!|" and probably a few other obscure variations.
In short, the history parser has always been very ad-hoc and deviates
from its own spec in several ways.
Here's a patch that fixes the unintended expansion, but it doesn't fix
the inconsistent behavior with !& !| et al. There should probably be
more method to this madness instead of multiple series of individual
character comparisons.
The (c == '"') condition is probably unnecessary because '!"' has been
handled much earlier, but the loop above this also tests all three
quotes, so ...
diff --git a/Src/hist.c b/Src/hist.c
index d1af30a..bd650e8 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -521,6 +521,12 @@ histsubchar(int c)
}
c = ingetc();
}
+ if (ptr == buf &&
+ (c == '}' || c == ';' || c == '\'' || c == '"' || c == '`')) {
+ /* Neither event nor word designator, no expansion */
+ safeinungetc(c);
+ return bangchar;
+ }
*ptr = 0;
if (!*buf) {
if (c != '%') {
next prev parent reply other threads:[~2013-10-08 2:56 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-07 15:55 Hauke Petersen
2013-10-08 2:56 ` Bart Schaefer [this message]
2013-10-08 14:31 ` Bart Schaefer
2013-10-08 14:44 ` Peter Stephenson
2013-10-08 15:43 ` Peter Stephenson
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=131007195612.ZM1029@torch.brasslantern.com \
--to=schaefer@brasslantern.com \
--cc=zsh-workers@zsh.org \
/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).