grep.c: display column number of first match
To prepare for 'git grep' learning '--column', teach grep.c's show_line() how to show the column of the first match on non-context lines. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Taylor Blau committed
Jun 22, 2018 at 10:49 UTC
89252cd069d4acf1c6c407f00c7a1cc2c6ad3953
1 file changed
+28
-5
grep.c
+28
-5
@@ -1405,7 +1405,7 @@ static int next_match(struct grep_opt *opt, char *bol, char *eol,
1405
}
1406
1407
static void show_line(struct grep_opt *opt, char *bol, char *eol,
1408
- const char *name, unsigned lno, char sign)
1408
+ const char *name, unsigned lno, ssize_t cno, char sign)
1409
{
1410
int rest = eol - bol;
1411
const char *match_color, *line_color = NULL;
@@ -1440,6 +1440,17 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
1440
output_color(opt, buf, strlen(buf), opt->color_lineno);
1441
output_sep(opt, sign);
1442
}
1443
+ /*
1444
+ * Treat 'cno' as the 1-indexed offset from the start of a non-context
1445
+ * line to its first match. Otherwise, 'cno' is 0 indicating that we are
1446
+ * being called with a context line.
1447
+ */
1448
+ if (opt->columnnum && cno) {
1449
+ char buf[32];
1450
+ xsnprintf(buf, sizeof(buf), "%"PRIuMAX, (uintmax_t)cno);
1451
+ output_color(opt, buf, strlen(buf), opt->color_columnno);
1452
+ output_sep(opt, sign);
1453
+ }
1454
if (opt->color) {
1455
regmatch_t match;
1456
enum grep_context ctx = GREP_CONTEXT_BODY;
@@ -1545,7 +1556,7 @@ static void show_funcname_line(struct grep_opt *opt, struct grep_source *gs,
1556
break;
1557
1558
if (match_funcname(opt, gs, bol, eol)) {
1548
- show_line(opt, bol, eol, gs->name, lno, '=');
1559
+ show_line(opt, bol, eol, gs->name, lno, 0, '=');
1560
break;
1561
}
1562
}
@@ -1610,7 +1621,7 @@ static void show_pre_context(struct grep_opt *opt, struct grep_source *gs,
1621
1622
while (*eol != '\n')
1623
eol++;
1613
- show_line(opt, bol, eol, gs->name, cur, sign);
1624
+ show_line(opt, bol, eol, gs->name, cur, 0, sign);
1625
bol = eol + 1;
1626
cur++;
1627
}
@@ -1809,6 +1820,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
1820
while (left) {
1821
char *eol, ch;
1822
int hit;
1823
+ ssize_t cno;
1824
ssize_t col = -1, icol = -1;
1825
1826
/*
@@ -1874,7 +1886,18 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
1886
show_pre_context(opt, gs, bol, eol, lno);
1887
else if (opt->funcname)
1888
show_funcname_line(opt, gs, bol, lno);
1877
- show_line(opt, bol, eol, gs->name, lno, ':');
1889
+ cno = opt->invert ? icol : col;
1890
+ if (cno < 0) {
1891
+ /*
1892
+ * A negative cno indicates that there was no
1893
+ * match on the line. We are thus inverted and
1894
+ * being asked to show all lines that _don't_
1895
+ * match a given expression. Therefore, set cno
1896
+ * to 0 to suggest the whole line matches.
1897
+ */
1898
+ cno = 0;
1899
+ }
1900
+ show_line(opt, bol, eol, gs->name, lno, cno + 1, ':');
1901
last_hit = lno;
1902
if (opt->funcbody)
1903
show_function = 1;
@@ -1903,7 +1926,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
1926
/* If the last hit is within the post context,
1927
* we need to show this line.
1928
*/
1906
- show_line(opt, bol, eol, gs->name, lno, '-');
1929
+ show_line(opt, bol, eol, gs->name, lno, col + 1, '-');
1930
}
1931
1932
next_line: