git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Taylor Blau <me@ttaylorr.com>
To: git@vger.kernel.org
Cc: avarab@gmail.com, peff@peff.net, gitster@pobox.com
Subject: [PATCH v2 0/7] grep.c: teach --column to 'git-grep(1)'
Date: Wed, 20 Jun 2018 15:05:30 -0500	[thread overview]
Message-ID: <cover.1529524852.git.me@ttaylorr.com> (raw)
In-Reply-To: <cover.1529365072.git.me@ttaylorr.com>

Hi,

Here is a re-roll of my series to add --column to 'git-grep(1)'. Since
last time, not much has changed other than the following:

  - Fix a typo where 'col', 'icol' were spelled as 'match', 'imatch'
    [1].

  - Disable short-circuiting OR when --column is given [2].

  - Disable early-return in match_line() when multiple patterns are
    given and --column is, too [3].

  - Add some more tests in t7810.

Thanks again for your kind and through review; hopefully this re-roll
should be OK to queue as-is.


Thanks,
Taylor

[1]: https://public-inbox.org/git/xmqqwouuvi0e.fsf@gitster-ct.c.googlers.com/
[2]: https://public-inbox.org/git/20180619174452.GA47272@syl.attlocal.net/
[3]: https://public-inbox.org/git/80b9a0b1-3849-7097-fe1a-dd80835d62ae@web.de/

Taylor Blau (7):
  Documentation/config.txt: camel-case lineNumber for consistency
  grep.c: expose {,inverted} match column in match_line()
  grep.[ch]: extend grep_opt to allow showing matched column
  grep.c: display column number of first match
  builtin/grep.c: add '--column' option to 'git-grep(1)'
  grep.c: add configuration variables to show matched option
  contrib/git-jump/git-jump: jump to exact location

 Documentation/config.txt   |   7 ++-
 Documentation/git-grep.txt |   9 ++-
 builtin/grep.c             |   1 +
 contrib/git-jump/README    |  12 +++-
 contrib/git-jump/git-jump  |   2 +-
 grep.c                     | 126 ++++++++++++++++++++++++++++---------
 grep.h                     |   2 +
 t/t7810-grep.sh            |  84 +++++++++++++++++++++++++
 8 files changed, 210 insertions(+), 33 deletions(-)

Inter-diff (since v1):

diff --git a/grep.c b/grep.c
index 8ffa94c791..08d3df2855 100644
--- a/grep.c
+++ b/grep.c
@@ -1257,8 +1257,8 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
 	return hit;
 }

-static int match_expr_eval(struct grep_expr *x, char *bol, char *eol,
-			   enum grep_context ctx, ssize_t *col,
+static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x, char *bol,
+			   char *eol, enum grep_context ctx, ssize_t *col,
 			   ssize_t *icol, int collect_hits)
 {
 	int h = 0;
@@ -1280,29 +1280,36 @@ static int match_expr_eval(struct grep_expr *x, char *bol, char *eol,
 		break;
 	case GREP_NODE_NOT:
 		/*
-		 * Upon visiting a GREP_NODE_NOT, imatch and match become
-		 * swapped.
+		 * Upon visiting a GREP_NODE_NOT, col and icol become swapped.
 		 */
-		h = !match_expr_eval(x->u.unary, bol, eol, ctx, icol, col, 0);
+		h = !match_expr_eval(opt, x->u.unary, bol, eol, ctx, icol, col,
+				     0);
 		break;
 	case GREP_NODE_AND:
-		if (!match_expr_eval(x->u.binary.left, bol, eol, ctx, col,
+		if (!match_expr_eval(opt, x->u.binary.left, bol, eol, ctx, col,
 				     icol, 0))
 			return 0;
-		h = match_expr_eval(x->u.binary.right, bol, eol, ctx, col,
+		h = match_expr_eval(opt, x->u.binary.right, bol, eol, ctx, col,
 				    icol, 0);
 		break;
 	case GREP_NODE_OR:
-		if (!collect_hits)
-			return (match_expr_eval(x->u.binary.left, bol, eol, ctx,
-						col, icol, 0) ||
-				match_expr_eval(x->u.binary.right, bol, eol,
-						ctx, col, icol, 0));
-		h = match_expr_eval(x->u.binary.left, bol, eol, ctx, col,
+		if (!(collect_hits || opt->columnnum)) {
+			/*
+			 * Don't short-circuit OR when given --column (or
+			 * collecting hits) to ensure we don't skip a later
+			 * child that would produce an earlier match.
+			 */
+			return (match_expr_eval(opt, x->u.binary.left, bol, eol,
+						ctx, col, icol, 0) ||
+				match_expr_eval(opt, x->u.binary.right, bol,
+						eol, ctx, col, icol, 0));
+		}
+		h = match_expr_eval(opt, x->u.binary.left, bol, eol, ctx, col,
 				    icol, 0);
-		x->u.binary.left->hit |= h;
-		h |= match_expr_eval(x->u.binary.right, bol, eol, ctx, col,
-				     icol, 1);
+		if (collect_hits)
+			x->u.binary.left->hit |= h;
+		h |= match_expr_eval(opt, x->u.binary.right, bol, eol, ctx, col,
+				     icol, collect_hits);
 		break;
 	default:
 		die("Unexpected node type (internal error) %d", x->node);
@@ -1317,7 +1324,7 @@ static int match_expr(struct grep_opt *opt, char *bol, char *eol,
 		      ssize_t *icol, int collect_hits)
 {
 	struct grep_expr *x = opt->pattern_expression;
-	return match_expr_eval(x, bol, eol, ctx, col, icol, collect_hits);
+	return match_expr_eval(opt, x, bol, eol, ctx, col, icol, collect_hits);
 }

 static int match_line(struct grep_opt *opt, char *bol, char *eol,
@@ -1325,6 +1332,7 @@ static int match_line(struct grep_opt *opt, char *bol, char *eol,
 		      enum grep_context ctx, int collect_hits)
 {
 	struct grep_pat *p;
+	int hit = 0;

 	if (opt->extended)
 		return match_expr(opt, bol, eol, ctx, col, icol,
@@ -1334,11 +1342,21 @@ static int match_line(struct grep_opt *opt, char *bol, char *eol,
 	for (p = opt->pattern_list; p; p = p->next) {
 		regmatch_t tmp;
 		if (match_one_pattern(p, bol, eol, ctx, &tmp, 0)) {
-			*col = tmp.rm_so;
-			return 1;
+			hit |= 1;
+			if (!opt->columnnum) {
+				/*
+				 * Without --column, any single match on a line
+				 * is enough to know that it needs to be
+				 * printed. With --column, scan _all_ patterns
+				 * to find the earliest.
+				 */
+				break;
+			}
+			if (*col < 0 || tmp.rm_so < *col)
+				*col = tmp.rm_so;
 		}
 	}
-	return 0;
+	return hit;
 }

 static int match_next_pattern(struct grep_pat *p, char *bol, char *eol,
@@ -1387,7 +1405,7 @@ static int next_match(struct grep_opt *opt, char *bol, char *eol,
 }

 static void show_line(struct grep_opt *opt, char *bol, char *eol,
-		      const char *name, unsigned lno, unsigned cno, char sign)
+		      const char *name, unsigned lno, ssize_t cno, char sign)
 {
 	int rest = eol - bol;
 	const char *match_color, *line_color = NULL;
@@ -1429,7 +1447,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
 	 */
 	if (opt->columnnum && cno) {
 		char buf[32];
-		xsnprintf(buf, sizeof(buf), "%d", cno);
+		xsnprintf(buf, sizeof(buf), "%zu", cno);
 		output_color(opt, buf, strlen(buf), opt->color_columnno);
 		output_sep(opt, sign);
 	}
@@ -1871,8 +1889,11 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
 			cno = opt->invert ? icol : col;
 			if (cno < 0) {
 				/*
-				 * A negative cno means that there was no match.
-				 * Clamp to the beginning of the line.
+				 * A negative cno indicates that there was no
+				 * match on the line. We are thus inverted and
+				 * being asked to show all lines that _don't_
+				 * match a given expression. Therefore, set cno
+				 * to 0 to suggest the whole line matches.
 				 */
 				cno = 0;
 			}
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index daaf7b4c44..bf0b572dab 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -139,6 +139,15 @@ do
 		test_cmp expected actual
 	'

+	test_expect_success "grep $L (with --column, double-negation)" '
+		{
+			echo ${HC}file:1:foo_mmap bar mmap baz
+		} >expected &&
+		git grep --column --not \( --not -e foo --or --not -e baz \) $H -- file \
+			>actual &&
+		test_cmp expected actual
+	'
+
 	test_expect_success "grep -w $L (with --column, -C)" '
 		{
 			echo ${HC}file:5:foo mmap bar
@@ -162,6 +171,18 @@ do
 		test_cmp expected actual
 	'

+	test_expect_success "grep -w $L (with non-extended patterns, --column)" '
+		{
+			echo ${HC}file:5:foo mmap bar
+			echo ${HC}file:10:foo_mmap bar
+			echo ${HC}file:10:foo_mmap bar mmap
+			echo ${HC}file:5:foo mmap bar_mmap
+			echo ${HC}file:10:foo_mmap bar mmap baz
+		} >expected &&
+		git grep --column -w -e bar -e mmap $H >actual &&
+		test_cmp expected actual
+	'
+
 	test_expect_success "grep -w $L" '
 		{
 			echo ${HC}file:1:foo mmap bar
--
2.17.0.582.gccdcbd54c

  parent reply	other threads:[~2018-06-20 20:05 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-18 23:43 [PATCH 0/7] grep.c: teach --column to 'git-grep(1)' Taylor Blau
2018-06-18 23:43 ` [PATCH 1/7] Documentation/config.txt: camel-case lineNumber for consistency Taylor Blau
2018-06-18 23:43 ` [PATCH 2/7] grep.c: expose {,inverted} match column in match_line() Taylor Blau
2018-06-19 16:49   ` Junio C Hamano
2018-06-19 17:02     ` Taylor Blau
2018-06-18 23:43 ` [PATCH 3/7] grep.[ch]: extend grep_opt to allow showing matched column Taylor Blau
2018-06-18 23:43 ` [PATCH 4/7] grep.c: display column number of first match Taylor Blau
2018-06-19 16:28   ` Jeff King
2018-06-19 16:34     ` Taylor Blau
2018-06-18 23:43 ` [PATCH 5/7] builtin/grep.c: add '--column' option to 'git-grep(1)' Taylor Blau
2018-06-18 23:43 ` [PATCH 6/7] grep.c: add configuration variables to show matched option Taylor Blau
2018-06-18 23:43 ` [PATCH 7/7] contrib/git-jump/git-jump: jump to exact location Taylor Blau
2018-06-19 16:35 ` [PATCH 0/7] grep.c: teach --column to 'git-grep(1)' Jeff King
2018-06-19 17:33   ` René Scharfe
2018-06-19 17:44     ` Taylor Blau
2018-06-19 17:50       ` René Scharfe
2018-06-19 20:26       ` René Scharfe
2018-06-19 17:48     ` Jeff King
2018-06-19 17:54       ` Taylor Blau
2018-06-19 17:58       ` Junio C Hamano
2018-06-19 18:02         ` Taylor Blau
2018-06-19 18:05         ` Jeff King
2018-06-19 18:09           ` Junio C Hamano
2018-06-19 18:50       ` René Scharfe
2018-06-19 19:11         ` Jeff King
2018-06-19 20:34           ` René Scharfe
2018-06-19 20:51             ` Junio C Hamano
2018-06-19 16:46 ` Junio C Hamano
2018-06-19 17:02   ` Taylor Blau
2018-06-19 22:51 ` Taylor Blau
2018-06-20 20:05 ` Taylor Blau [this message]
2018-06-20 20:05   ` [PATCH v2 1/7] Documentation/config.txt: camel-case lineNumber for consistency Taylor Blau
2018-06-20 20:05   ` [PATCH v2 2/7] grep.c: expose {,inverted} match column in match_line() Taylor Blau
2018-06-20 20:05   ` [PATCH v2 3/7] grep.[ch]: extend grep_opt to allow showing matched column Taylor Blau
2018-06-20 20:05   ` [PATCH v2 4/7] grep.c: display column number of first match Taylor Blau
2018-06-20 20:05   ` [PATCH v2 5/7] builtin/grep.c: add '--column' option to 'git-grep(1)' Taylor Blau
2018-06-20 20:05   ` [PATCH v2 6/7] grep.c: add configuration variables to show matched option Taylor Blau
2018-06-20 20:05   ` [PATCH v2 7/7] contrib/git-jump/git-jump: jump to exact location Taylor Blau
2018-06-21 11:53   ` [PATCH v2 0/7] grep.c: teach --column to 'git-grep(1)' Jeff King
2018-06-21 12:01     ` Jeff King
2018-06-22 21:45       ` Johannes Schindelin
2018-06-22 22:26         ` Jeff King
2018-06-21 20:52     ` Junio C Hamano
2018-06-21 21:45     ` Taylor Blau
2018-06-22  7:22       ` Jeff King
2018-06-22 15:49 ` [PATCH v3 " Taylor Blau
2018-06-22 15:49   ` [PATCH v3 1/7] Documentation/config.txt: camel-case lineNumber for consistency Taylor Blau
2018-06-22 15:49   ` [PATCH v3 2/7] grep.c: expose {,inverted} match column in match_line() Taylor Blau
2018-06-22 15:49   ` [PATCH v3 3/7] grep.[ch]: extend grep_opt to allow showing matched column Taylor Blau
2018-06-22 15:49   ` [PATCH v3 4/7] grep.c: display column number of first match Taylor Blau
2018-06-22 15:49   ` [PATCH v3 5/7] builtin/grep.c: add '--column' option to 'git-grep(1)' Taylor Blau
2018-06-22 15:49   ` [PATCH v3 6/7] grep.c: add configuration variables to show matched option Taylor Blau
2018-06-22 15:49   ` [PATCH v3 7/7] contrib/git-jump/git-jump: jump to exact location Taylor Blau
2018-06-25 18:43   ` [PATCH v3 0/7] grep.c: teach --column to 'git-grep(1)' Jeff King
2018-06-25 18:47     ` Taylor Blau
2018-06-26 16:45       ` Junio C Hamano

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=cover.1529524852.git.me@ttaylorr.com \
    --to=me@ttaylorr.com \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    /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).