Merge branch 'rs/threaded-grep-context'
authorJunio C Hamano <gitster@pobox.com>
Sat, 3 Apr 2010 19:28:39 +0000 (12:28 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 3 Apr 2010 19:28:39 +0000 (12:28 -0700)
* rs/threaded-grep-context:
grep: enable threading for context line printing

Conflicts:
grep.c

1  2 
builtin/grep.c
grep.c
diff --combined builtin/grep.c
index 9d30ddb28df16f834c9fbb3bf6ba8cc172a502b3,f427d55f274889a7fcfbd12e3c21678ad947f32e..8e928e217041a159f4a962f0883d740aa84536d7
@@@ -96,6 -96,9 +96,9 @@@ static pthread_cond_t cond_write
  /* Signalled when we are finished with everything. */
  static pthread_cond_t cond_result;
  
+ static int print_hunk_marks_between_files;
+ static int printed_something;
  static void add_work(enum work_type type, char *name, void *id)
  {
        grep_lock();
@@@ -159,7 -162,12 +162,12 @@@ static void work_done(struct work_item 
        for(; todo[todo_done].done && todo_done != todo_start;
            todo_done = (todo_done+1) % ARRAY_SIZE(todo)) {
                w = &todo[todo_done];
-               write_or_die(1, w->out.buf, w->out.len);
+               if (w->out.len) {
+                       if (print_hunk_marks_between_files && printed_something)
+                               write_or_die(1, "--\n", 3);
+                       write_or_die(1, w->out.buf, w->out.len);
+                       printed_something = 1;
+               }
                free(w->name);
                free(w->identifier);
        }
@@@ -289,7 -297,6 +297,7 @@@ static int wait_all(void
  static int grep_config(const char *var, const char *value, void *cb)
  {
        struct grep_opt *opt = cb;
 +      char *color = NULL;
  
        switch (userdiff_config(var, value)) {
        case 0: break;
        default: return 0;
        }
  
 -      if (!strcmp(var, "color.grep")) {
 +      if (!strcmp(var, "color.grep"))
                opt->color = git_config_colorbool(var, value, -1);
 -              return 0;
 -      }
 -      if (!strcmp(var, "color.grep.match")) {
 +      else if (!strcmp(var, "color.grep.context"))
 +              color = opt->color_context;
 +      else if (!strcmp(var, "color.grep.filename"))
 +              color = opt->color_filename;
 +      else if (!strcmp(var, "color.grep.function"))
 +              color = opt->color_function;
 +      else if (!strcmp(var, "color.grep.linenumber"))
 +              color = opt->color_lineno;
 +      else if (!strcmp(var, "color.grep.match"))
 +              color = opt->color_match;
 +      else if (!strcmp(var, "color.grep.selected"))
 +              color = opt->color_selected;
 +      else if (!strcmp(var, "color.grep.separator"))
 +              color = opt->color_sep;
 +      else
 +              return git_color_default_config(var, value, cb);
 +      if (color) {
                if (!value)
                        return config_error_nonbool(var);
 -              color_parse(value, var, opt->color_match);
 -              return 0;
 +              color_parse(value, var, color);
        }
 -      return git_color_default_config(var, value, cb);
 +      return 0;
  }
  
  /*
@@@ -886,13 -880,7 +894,13 @@@ int cmd_grep(int argc, const char **arg
        opt.regflags = REG_NEWLINE;
        opt.max_depth = -1;
  
 -      strcpy(opt.color_match, GIT_COLOR_RED GIT_COLOR_BOLD);
 +      strcpy(opt.color_context, "");
 +      strcpy(opt.color_filename, "");
 +      strcpy(opt.color_function, "");
 +      strcpy(opt.color_lineno, "");
 +      strcpy(opt.color_match, GIT_COLOR_BOLD_RED);
 +      strcpy(opt.color_selected, "");
 +      strcpy(opt.color_sep, GIT_COLOR_CYAN);
        opt.color = -1;
        git_config(grep_config, &opt);
        if (opt.color == -1)
        if (online_cpus() == 1 || !grep_threads_ok(&opt))
                use_threads = 0;
  
-       if (use_threads)
+       if (use_threads) {
+               if (opt.pre_context || opt.post_context)
+                       print_hunk_marks_between_files = 1;
                start_threads(&opt);
+       }
  #else
        use_threads = 0;
  #endif
diff --combined grep.c
index fdc42062687fa6b8bb77c8d09ed58aee9107692d,e5f06e435f2a8100676cd2a5b78312fcd8631717..543b1d53784c16020dea089f23c431c7f2608425
--- 1/grep.c
--- 2/grep.c
+++ b/grep.c
@@@ -304,28 -304,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);
  }
  
@@@ -563,31 -544,29 +563,30 @@@ static void show_line(struct grep_opt *
                      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 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
-                               opt->show_hunk_mark = 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;
                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);
  }
  
@@@ -772,14 -748,6 +771,6 @@@ int grep_threads_ok(const struct grep_o
            !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;
  }
  
@@@ -801,11 -769,14 +792,14 @@@ static int grep_buffer_1(struct grep_op
        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:
                                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;
                        }
         */
        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;