X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=grep.c;h=543b1d53784c16020dea089f23c431c7f2608425;hb=c05b988a69c10d7eef2f34932eed61923c18b4a5;hp=a0864f1cbbe5fcc6f28eb57a08ebfd9a76c87da6;hpb=89cd4aa8624de4fa80469ab9ef8482f44b2cc2db;p=git.git diff --git a/grep.c b/grep.c index a0864f1cb..543b1d537 100644 --- a/grep.c +++ b/grep.c @@ -11,8 +11,8 @@ void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field fie p->no = 0; p->token = GREP_PATTERN_HEAD; p->field = field; - *opt->pattern_tail = p; - opt->pattern_tail = &p->next; + *opt->header_tail = p; + opt->header_tail = &p->next; p->next = NULL; } @@ -184,9 +184,26 @@ static struct grep_expr *compile_pattern_expr(struct grep_pat **list) void compile_grep_patterns(struct grep_opt *opt) { struct grep_pat *p; - - if (opt->all_match) - opt->extended = 1; + struct grep_expr *header_expr = NULL; + + if (opt->header_list) { + p = opt->header_list; + header_expr = compile_pattern_expr(&p); + if (p) + die("incomplete pattern expression: %s", p->pattern); + for (p = opt->header_list; p; p = p->next) { + switch (p->token) { + case GREP_PATTERN: /* atom */ + case GREP_PATTERN_HEAD: + case GREP_PATTERN_BODY: + compile_regexp(p, opt); + break; + default: + opt->extended = 1; + break; + } + } + } for (p = opt->pattern_list; p; p = p->next) { switch (p->token) { @@ -201,7 +218,9 @@ void compile_grep_patterns(struct grep_opt *opt) } } - if (!opt->extended) + if (opt->all_match || header_expr) + opt->extended = 1; + else if (!opt->extended) return; /* Then bundle them up in an expression. @@ -212,6 +231,21 @@ void compile_grep_patterns(struct grep_opt *opt) opt->pattern_expression = compile_pattern_expr(&p); if (p) die("incomplete pattern expression: %s", p->pattern); + + if (!header_expr) + return; + + if (opt->pattern_expression) { + struct grep_expr *z; + z = xcalloc(1, sizeof(*z)); + z->node = GREP_NODE_OR; + z->u.binary.left = opt->pattern_expression; + z->u.binary.right = header_expr; + opt->pattern_expression = z; + } else { + opt->pattern_expression = header_expr; + } + opt->all_match = 1; } static void free_pattern_expr(struct grep_expr *x) @@ -270,9 +304,28 @@ static int word_char(char ch) return isalnum(ch) || ch == '_'; } +static void output_color(struct grep_opt *opt, const void *data, size_t size, + const char *color) +{ + if (opt->color && color && color[0]) { + opt->output(opt, color, strlen(color)); + opt->output(opt, data, size); + opt->output(opt, GIT_COLOR_RESET, strlen(GIT_COLOR_RESET)); + } else + opt->output(opt, data, size); +} + +static void output_sep(struct grep_opt *opt, char sign) +{ + if (opt->null_following_name) + opt->output(opt, "\0", 1); + else + output_color(opt, &sign, 1, opt->color_sep); +} + static void show_name(struct grep_opt *opt, const char *name) { - opt->output(opt, name, strlen(name)); + output_color(opt, name, strlen(name), opt->color_filename); opt->output(opt, opt->null_following_name ? "\0" : "\n", 1); } @@ -510,31 +563,30 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol, const char *name, unsigned lno, char sign) { int rest = eol - bol; - char sign_str[1]; + char *line_color = NULL; - sign_str[0] = sign; if (opt->pre_context || opt->post_context) { if (opt->last_shown == 0) { - if (opt->show_hunk_mark) - opt->output(opt, "--\n", 3); - else - opt->show_hunk_mark = 1; - } else if (lno > opt->last_shown + 1) - opt->output(opt, "--\n", 3); + if (opt->show_hunk_mark) { + output_color(opt, "--", 2, opt->color_sep); + opt->output(opt, "\n", 1); + } + } else if (lno > opt->last_shown + 1) { + output_color(opt, "--", 2, opt->color_sep); + opt->output(opt, "\n", 1); + } } opt->last_shown = lno; - if (opt->null_following_name) - sign_str[0] = '\0'; if (opt->pathname) { - opt->output(opt, name, strlen(name)); - opt->output(opt, sign_str, 1); + output_color(opt, name, strlen(name), opt->color_filename); + output_sep(opt, sign); } if (opt->linenum) { char buf[32]; snprintf(buf, sizeof(buf), "%d", lno); - opt->output(opt, buf, strlen(buf)); - opt->output(opt, sign_str, 1); + output_color(opt, buf, strlen(buf), opt->color_lineno); + output_sep(opt, sign); } if (opt->color) { regmatch_t match; @@ -542,25 +594,28 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol, int ch = *eol; int eflags = 0; + if (sign == ':') + line_color = opt->color_selected; + else if (sign == '-') + line_color = opt->color_context; + else if (sign == '=') + line_color = opt->color_function; *eol = '\0'; while (next_match(opt, bol, eol, ctx, &match, eflags)) { if (match.rm_so == match.rm_eo) break; - opt->output(opt, bol, match.rm_so); - opt->output(opt, opt->color_match, - strlen(opt->color_match)); - opt->output(opt, bol + match.rm_so, - (int)(match.rm_eo - match.rm_so)); - opt->output(opt, GIT_COLOR_RESET, - strlen(GIT_COLOR_RESET)); + output_color(opt, bol, match.rm_so, line_color); + output_color(opt, bol + match.rm_so, + match.rm_eo - match.rm_so, + opt->color_match); bol += match.rm_eo; rest -= match.rm_eo; eflags = REG_NOTBOL; } *eol = ch; } - opt->output(opt, bol, rest); + output_color(opt, bol, rest, line_color); opt->output(opt, "\n", 1); } @@ -716,14 +771,6 @@ int grep_threads_ok(const struct grep_opt *opt) !opt->name_only) return 0; - /* If we are showing hunk marks, we should not do it for the - * first match. The synchronization problem we get for this - * constraint is not yet solved, so we disable threading in - * this case. - */ - if (opt->pre_context || opt->post_context) - return 0; - return 1; } @@ -745,11 +792,14 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name, enum grep_context ctx = GREP_CONTEXT_HEAD; xdemitconf_t xecfg; - opt->last_shown = 0; - if (!opt->output) opt->output = std_output; + if (opt->last_shown && (opt->pre_context || opt->post_context) && + opt->output == std_output) + opt->show_hunk_mark = 1; + opt->last_shown = 0; + if (buffer_is_binary(buf, size)) { switch (opt->binary) { case GREP_BINARY_DEFAULT: @@ -823,7 +873,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name, return 1; if (binary_match_only) { opt->output(opt, "Binary file ", 12); - opt->output(opt, name, strlen(name)); + output_color(opt, name, strlen(name), + opt->color_filename); opt->output(opt, " matches\n", 9); return 1; } @@ -882,9 +933,9 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name, */ if (opt->count && count) { char buf[32]; - opt->output(opt, name, strlen(name)); - snprintf(buf, sizeof(buf), "%c%u\n", - opt->null_following_name ? '\0' : ':', count); + output_color(opt, name, strlen(name), opt->color_filename); + output_sep(opt, ':'); + snprintf(buf, sizeof(buf), "%u\n", count); opt->output(opt, buf, strlen(buf)); } return !!last_hit;