Skip to content

Commit 3f566c4

Browse files
effective-lightgitster
authored andcommitted
grep: refactor next_match() and match_one_pattern() for external use
These changes are made in preparation of, the colorization support for the "git log" subcommands that, rely on regex functionality (i.e. "--author", "--committer" and "--grep"). These changes are necessary primarily because match_one_pattern() expects header lines to be prefixed, however, in pretty, the prefixes are stripped from the lines because the name-email pairs need to go through additional parsing, before they can be printed and because next_match() doesn't handle the case of "ctx == GREP_CONTEXT_HEAD" at all. So, teach next_match() how to handle the new case and move match_one_pattern()'s core logic to headerless_match_one_pattern() while preserving match_one_pattern()'s uses that depend on the additional processing. Signed-off-by: Hamza Mahfooz <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 28ecef4 commit 3f566c4

File tree

2 files changed

+58
-30
lines changed

2 files changed

+58
-30
lines changed

grep.c

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -944,10 +944,10 @@ static struct {
944944
{ "reflog ", 7 },
945945
};
946946

947-
static int match_one_pattern(struct grep_pat *p,
948-
const char *bol, const char *eol,
949-
enum grep_context ctx,
950-
regmatch_t *pmatch, int eflags)
947+
static int headerless_match_one_pattern(struct grep_pat *p,
948+
const char *bol, const char *eol,
949+
enum grep_context ctx,
950+
regmatch_t *pmatch, int eflags)
951951
{
952952
int hit = 0;
953953
const char *start = bol;
@@ -956,25 +956,6 @@ static int match_one_pattern(struct grep_pat *p,
956956
((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD)))
957957
return 0;
958958

959-
if (p->token == GREP_PATTERN_HEAD) {
960-
const char *field;
961-
size_t len;
962-
assert(p->field < ARRAY_SIZE(header_field));
963-
field = header_field[p->field].field;
964-
len = header_field[p->field].len;
965-
if (strncmp(bol, field, len))
966-
return 0;
967-
bol += len;
968-
switch (p->field) {
969-
case GREP_HEADER_AUTHOR:
970-
case GREP_HEADER_COMMITTER:
971-
strip_timestamp(bol, &eol);
972-
break;
973-
default:
974-
break;
975-
}
976-
}
977-
978959
again:
979960
hit = patmatch(p, bol, eol, pmatch, eflags);
980961

@@ -1025,6 +1006,36 @@ static int match_one_pattern(struct grep_pat *p,
10251006
return hit;
10261007
}
10271008

1009+
static int match_one_pattern(struct grep_pat *p,
1010+
const char *bol, const char *eol,
1011+
enum grep_context ctx, regmatch_t *pmatch,
1012+
int eflags)
1013+
{
1014+
const char *field;
1015+
size_t len;
1016+
1017+
if (p->token == GREP_PATTERN_HEAD) {
1018+
assert(p->field < ARRAY_SIZE(header_field));
1019+
field = header_field[p->field].field;
1020+
len = header_field[p->field].len;
1021+
if (strncmp(bol, field, len))
1022+
return 0;
1023+
bol += len;
1024+
1025+
switch (p->field) {
1026+
case GREP_HEADER_AUTHOR:
1027+
case GREP_HEADER_COMMITTER:
1028+
strip_timestamp(bol, &eol);
1029+
break;
1030+
default:
1031+
break;
1032+
}
1033+
}
1034+
1035+
return headerless_match_one_pattern(p, bol, eol, ctx, pmatch, eflags);
1036+
}
1037+
1038+
10281039
static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x,
10291040
const char *bol, const char *eol,
10301041
enum grep_context ctx, ssize_t *col,
@@ -1143,7 +1154,7 @@ static int match_next_pattern(struct grep_pat *p,
11431154
{
11441155
regmatch_t match;
11451156

1146-
if (!match_one_pattern(p, bol, eol, ctx, &match, eflags))
1157+
if (!headerless_match_one_pattern(p, bol, eol, ctx, &match, eflags))
11471158
return 0;
11481159
if (match.rm_so < 0 || match.rm_eo < 0)
11491160
return 0;
@@ -1158,19 +1169,26 @@ static int match_next_pattern(struct grep_pat *p,
11581169
return 1;
11591170
}
11601171

1161-
static int next_match(struct grep_opt *opt,
1162-
const char *bol, const char *eol,
1163-
enum grep_context ctx, regmatch_t *pmatch, int eflags)
1172+
int grep_next_match(struct grep_opt *opt,
1173+
const char *bol, const char *eol,
1174+
enum grep_context ctx, regmatch_t *pmatch,
1175+
enum grep_header_field field, int eflags)
11641176
{
11651177
struct grep_pat *p;
11661178
int hit = 0;
11671179

11681180
pmatch->rm_so = pmatch->rm_eo = -1;
11691181
if (bol < eol) {
1170-
for (p = opt->pattern_list; p; p = p->next) {
1182+
for (p = ((ctx == GREP_CONTEXT_HEAD)
1183+
? opt->header_list : opt->pattern_list);
1184+
p; p = p->next) {
11711185
switch (p->token) {
1172-
case GREP_PATTERN: /* atom */
11731186
case GREP_PATTERN_HEAD:
1187+
if ((field != GREP_HEADER_FIELD_MAX) &&
1188+
(p->field != field))
1189+
continue;
1190+
/* fall thru */
1191+
case GREP_PATTERN: /* atom */
11741192
case GREP_PATTERN_BODY:
11751193
hit |= match_next_pattern(p, bol, eol, ctx,
11761194
pmatch, eflags);
@@ -1261,7 +1279,8 @@ static void show_line(struct grep_opt *opt,
12611279
else if (sign == '=')
12621280
line_color = opt->colors[GREP_COLOR_FUNCTION];
12631281
}
1264-
while (next_match(opt, bol, eol, ctx, &match, eflags)) {
1282+
while (grep_next_match(opt, bol, eol, ctx, &match,
1283+
GREP_HEADER_FIELD_MAX, eflags)) {
12651284
if (match.rm_so == match.rm_eo)
12661285
break;
12671286

grep.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,15 @@ void compile_grep_patterns(struct grep_opt *opt);
191191
void free_grep_patterns(struct grep_opt *opt);
192192
int grep_buffer(struct grep_opt *opt, const char *buf, unsigned long size);
193193

194+
/* The field parameter is only used to filter header patterns
195+
* (where appropriate). If filtering isn't desirable
196+
* GREP_HEADER_FIELD_MAX should be supplied.
197+
*/
198+
int grep_next_match(struct grep_opt *opt,
199+
const char *bol, const char *eol,
200+
enum grep_context ctx, regmatch_t *pmatch,
201+
enum grep_header_field field, int eflags);
202+
194203
struct grep_source {
195204
char *name;
196205

0 commit comments

Comments
 (0)