From: Johannes Schindelin <Johannes.Schindelin@gmx.de>
To: skimo@liacs.nl
Cc: Junio C Hamano <gitster@pobox.com>, git@vger.kernel.org
Subject: Re: [PATCH v3] revision: allow selection of commits that do not match a pattern
Date: Sun, 8 Jul 2007 15:22:06 +0100 (BST) [thread overview]
Message-ID: <Pine.LNX.4.64.0707081519230.4248@racer.site> (raw)
In-Reply-To: <20070708105719.GH1528MdfPADPa@greensroom.kotnet.org>
Hi,
just to give you an impression of what I had in mind, here is a WIP. It
is not completely thought through, for example I did not make up my mind
how to handle something like "--not --not-at-all <pattern>". Oh, and the
code for non-status_only is not there. And builtin-grep does not see any
of this, yet. But you'll get the idea:
---
grep.c | 19 +++++++++++++++----
grep.h | 3 +++
revision.c | 13 ++++++++++++-
3 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/grep.c b/grep.c
index f67d671..40a2620 100644
--- a/grep.c
+++ b/grep.c
@@ -66,20 +66,24 @@ static struct grep_expr *compile_pattern_atom(struct grep_pat **list)
static struct grep_expr *compile_pattern_not(struct grep_pat **list)
{
+ const char *what;
struct grep_pat *p;
struct grep_expr *x;
p = *list;
switch (p->token) {
case GREP_NOT:
+ case GREP_NOT_AT_ALL:
+ what = p->token == GREP_NOT ? "--not" : "--not-at-all";
if (!p->next)
- die("--not not followed by pattern expression");
+ die("%s not followed by pattern expression", what);
*list = p->next;
x = xcalloc(1, sizeof (struct grep_expr));
- x->node = GREP_NODE_NOT;
+ x->node = p->token == GREP_NOT ?
+ GREP_NODE_NOT : GREP_NODE_NOT_AT_ALL;
x->u.unary = compile_pattern_not(list);
if (!x->u.unary)
- die("--not followed by non pattern expression");
+ die("%s followed by non pattern expression", what);
return x;
default:
return compile_pattern_atom(list);
@@ -173,6 +177,7 @@ static void free_pattern_expr(struct grep_expr *x)
case GREP_NODE_ATOM:
break;
case GREP_NODE_NOT:
+ case GREP_NODE_NOT_AT_ALL:
free_pattern_expr(x->u.unary);
break;
case GREP_NODE_AND:
@@ -316,6 +321,10 @@ static int match_expr_eval(struct grep_opt *o,
case GREP_NODE_NOT:
h = !match_expr_eval(o, x->u.unary, bol, eol, ctx, 0);
break;
+ case GREP_NODE_NOT_AT_ALL:
+ if (match_expr_eval(o, x->u.unary, bol, eol, ctx, 0))
+ o->not_at_all = 1;
+ break;
case GREP_NODE_AND:
if (!collect_hits)
return (match_expr_eval(o, x->u.binary.left,
@@ -382,6 +391,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
unsigned count = 0;
enum grep_context ctx = GREP_CONTEXT_HEAD;
+ opt->not_at_all = 0;
+
if (buffer_is_binary(buf, size)) {
switch (opt->binary) {
case GREP_BINARY_DEFAULT:
@@ -500,7 +511,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
return 0;
if (opt->status_only)
- return 0;
+ return !opt->not_at_all;
if (opt->unmatch_name_only) {
/* We did not see any hit, so we want to show this */
printf("%s\n", name);
diff --git a/grep.h b/grep.h
index d252dd2..f80a1c2 100644
--- a/grep.h
+++ b/grep.h
@@ -10,6 +10,7 @@ enum grep_pat_token {
GREP_CLOSE_PAREN,
GREP_NOT,
GREP_OR,
+ GREP_NOT_AT_ALL,
};
enum grep_context {
@@ -31,6 +32,7 @@ enum grep_expr_node {
GREP_NODE_NOT,
GREP_NODE_AND,
GREP_NODE_OR,
+ GREP_NODE_NOT_AT_ALL,
};
struct grep_expr {
@@ -68,6 +70,7 @@ struct grep_opt {
unsigned extended:1;
unsigned relative:1;
unsigned pathname:1;
+ unsigned not_at_all:1; /* is set if the pattern was seen */
int regflags;
unsigned pre_context;
unsigned post_context;
diff --git a/revision.c b/revision.c
index 5184716..3df8a57 100644
--- a/revision.c
+++ b/revision.c
@@ -823,6 +823,7 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
{
+ int negate = *ptn == '!';
if (!revs->grep_filter) {
struct grep_opt *opt = xcalloc(1, sizeof(*opt));
opt->status_only = 1;
@@ -830,6 +831,13 @@ static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token
opt->regflags = REG_NEWLINE;
revs->grep_filter = opt;
}
+ if (negate) {
+ revs->grep_filter->extended = 1;
+ append_grep_pattern(revs->grep_filter, ptn,
+ "command line", 0, GREP_NOT_AT_ALL);
+ }
+ if (negate || ( *ptn == '\\' && ptn[1] == '!'))
+ ptn++;
append_grep_pattern(revs->grep_filter, ptn,
"command line", 0, what);
}
@@ -839,7 +847,10 @@ static void add_header_grep(struct rev_info *revs, const char *field, const char
char *pat;
const char *prefix;
int patlen, fldlen;
+ int negate = *pattern == '!';
+ if (negate || (*pattern == '\\' && pattern[1] == '!'))
+ pattern++;
fldlen = strlen(field);
patlen = strlen(pattern);
pat = xmalloc(patlen + fldlen + 10);
@@ -848,7 +859,7 @@ static void add_header_grep(struct rev_info *revs, const char *field, const char
prefix = "";
pattern++;
}
- sprintf(pat, "^%s %s%s", field, prefix, pattern);
+ sprintf(pat, "%s^%s %s%s", negate ? "!" : "", field, prefix, pattern);
add_grep(revs, pat, GREP_PATTERN_HEAD);
}
next prev parent reply other threads:[~2007-07-08 14:29 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-07 15:30 [PATCH] revision: allow selection of commits that do not match a pattern Sven Verdoolaege
2007-07-07 16:27 ` Johannes Schindelin
2007-07-07 16:52 ` Sven Verdoolaege
2007-07-07 17:33 ` Johannes Schindelin
2007-07-07 18:42 ` Sven Verdoolaege
2007-07-07 19:35 ` Johannes Schindelin
2007-07-07 20:22 ` Sven Verdoolaege
2007-07-08 10:57 ` [PATCH v3] " Sven Verdoolaege
2007-07-08 14:22 ` Johannes Schindelin [this message]
2007-07-08 14:57 ` Sven Verdoolaege
2007-07-11 17:42 ` Jeff King
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=Pine.LNX.4.64.0707081519230.4248@racer.site \
--to=johannes.schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=skimo@liacs.nl \
/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.
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).