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 the format of "bol" differs in the context that I require to use match_one_pattern() in and because next_match() doesn't handle the case of "ctx == GREP_CONTEXT_HEAD" at all. So, teach each function how to handle the new cases. Signed-off-by: Hamza Mahfooz <someguy@xxxxxxxxxxxxxxxxxxx> --- v5: separate grep changes from pretty changes. --- grep.c | 53 ++++++++++++++++++++++++++++++++++++----------------- grep.h | 3 +++ 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/grep.c b/grep.c index 424a39591b..e77c8643d2 100644 --- a/grep.c +++ b/grep.c @@ -951,31 +951,38 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol, enum grep_context ctx, regmatch_t *pmatch, int eflags) { + const char *field; + size_t len; int hit = 0; int saved_ch = 0; const char *start = bol; + const char *end = eol; if ((p->token != GREP_PATTERN) && - ((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD))) + ((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD)) && + ((p->token == GREP_PATTERN_BODY) != (ctx == GREP_CONTEXT_BODY))) return 0; if (p->token == GREP_PATTERN_HEAD) { - const char *field; - size_t len; - assert(p->field < ARRAY_SIZE(header_field)); - field = header_field[p->field].field; - len = header_field[p->field].len; - if (strncmp(bol, field, len)) - return 0; - bol += len; switch (p->field) { case GREP_HEADER_AUTHOR: case GREP_HEADER_COMMITTER: saved_ch = strip_timestamp(bol, &eol); + if (eol == end) + goto again; break; default: break; } + + assert(p->field < ARRAY_SIZE(header_field)); + field = header_field[p->field].field; + len = header_field[p->field].len; + + if (strncmp(bol, field, len)) + goto restore; + + bol += len; } again: @@ -1021,12 +1028,17 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol, goto again; } } - if (p->token == GREP_PATTERN_HEAD && saved_ch) - *eol = saved_ch; + if (hit) { pmatch[0].rm_so += bol - start; pmatch[0].rm_eo += bol - start; } + +restore: + if (p->token == GREP_PATTERN_HEAD && saved_ch) + *eol = saved_ch; + + return hit; } @@ -1159,21 +1171,27 @@ static int match_next_pattern(struct grep_pat *p, char *bol, char *eol, return 1; } -static int next_match(struct grep_opt *opt, char *bol, char *eol, - enum grep_context ctx, regmatch_t *pmatch, int eflags) +int grep_next_match(struct grep_opt *opt, char *bol, char *eol, + enum grep_context ctx, regmatch_t *pmatch, + enum grep_header_field field, int eflags) { struct grep_pat *p; int hit = 0; pmatch->rm_so = pmatch->rm_eo = -1; if (bol < eol) { - for (p = opt->pattern_list; p; p = p->next) { + for (p = ((ctx == GREP_CONTEXT_HEAD) + ? opt->header_list : opt->pattern_list); + p; p = p->next) { switch (p->token) { case GREP_PATTERN: /* atom */ case GREP_PATTERN_HEAD: case GREP_PATTERN_BODY: - hit |= match_next_pattern(p, bol, eol, ctx, - pmatch, eflags); + if ((field == GREP_HEADER_FIELD_MAX) || + (p->field == field)) + hit |= match_next_pattern(p, bol, eol, + ctx, pmatch, + eflags); break; default: break; @@ -1262,7 +1280,8 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol, line_color = opt->colors[GREP_COLOR_FUNCTION]; } *eol = '\0'; - while (next_match(opt, bol, eol, ctx, &match, eflags)) { + while (grep_next_match(opt, bol, eol, ctx, &match, + GREP_HEADER_FIELD_MAX, eflags)) { if (match.rm_so == match.rm_eo) break; diff --git a/grep.h b/grep.h index 72f82b1e30..d2943e29ea 100644 --- a/grep.h +++ b/grep.h @@ -177,6 +177,9 @@ void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const void compile_grep_patterns(struct grep_opt *opt); void free_grep_patterns(struct grep_opt *opt); int grep_buffer(struct grep_opt *opt, char *buf, unsigned long size); +int grep_next_match(struct grep_opt *opt, char *bol, char *eol, + enum grep_context ctx, regmatch_t *pmatch, + enum grep_header_field field, int eflags); struct grep_source { char *name; -- 2.33.0