Documentation: git-send-email: fix submission port number
[gitweb.git] / grep.c
diff --git a/grep.c b/grep.c
index 3a5c138476e5bc643656ec7a6e41da9fa3168969..5d162dae6e43cdfcf6b20627df088a73cbfa98dc 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "grep.h"
+#include "userdiff.h"
 #include "xdiff-interface.h"
 
 void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field field, const char *pat)
@@ -490,18 +491,14 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
 {
        int rest = eol - bol;
 
-       if (opt->pre_context || opt->post_context || opt->funcname) {
+       if (opt->pre_context || opt->post_context) {
                if (opt->last_shown == 0) {
                        if (opt->show_hunk_mark)
-                               fputs(opt->funcname ? "==\n" : "--\n", stdout);
+                               fputs("--\n", stdout);
                        else
                                opt->show_hunk_mark = 1;
-               } else if (lno > opt->last_shown + 1) {
-                       if (opt->pre_context || opt->post_context)
-                               fputs((sign == '=') ? "==\n" : "--\n", stdout);
-                       else if (sign == '=')
-                               fputs("==\n", stdout);
-               }
+               } else if (lno > opt->last_shown + 1)
+                       fputs("--\n", stdout);
        }
        opt->last_shown = lno;
 
@@ -535,8 +532,15 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
        printf("%.*s\n", rest, bol);
 }
 
-static int match_funcname(char *bol, char *eol)
+static int match_funcname(struct grep_opt *opt, char *bol, char *eol)
 {
+       xdemitconf_t *xecfg = opt->priv;
+       if (xecfg && xecfg->find_func) {
+               char buf[1];
+               return xecfg->find_func(bol, eol - bol, buf, 1,
+                                       xecfg->find_func_priv) >= 0;
+       }
+
        if (bol == eol)
                return 0;
        if (isalpha(*bol) || *bol == '_' || *bol == '$')
@@ -557,7 +561,7 @@ static void show_funcname_line(struct grep_opt *opt, const char *name,
                if (lno <= opt->last_shown)
                        break;
 
-               if (match_funcname(bol, eol)) {
+               if (match_funcname(opt, bol, eol)) {
                        show_line(opt, bol, eol, name, lno, '=');
                        break;
                }
@@ -582,7 +586,7 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
                while (bol > buf && bol[-1] != '\n')
                        bol--;
                cur--;
-               if (funcname_needed && match_funcname(bol, eol)) {
+               if (funcname_needed && match_funcname(opt, bol, eol)) {
                        funcname_lno = cur;
                        funcname_needed = 0;
                }
@@ -614,6 +618,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
        int binary_match_only = 0;
        unsigned count = 0;
        enum grep_context ctx = GREP_CONTEXT_HEAD;
+       xdemitconf_t xecfg;
 
        opt->last_shown = 0;
 
@@ -630,6 +635,17 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                }
        }
 
+       memset(&xecfg, 0, sizeof(xecfg));
+       if (opt->funcname && !opt->unmatch_name_only && !opt->status_only &&
+           !opt->name_only && !binary_match_only && !collect_hits) {
+               struct userdiff_driver *drv = userdiff_find_by_path(name);
+               if (drv && drv->funcname.pattern) {
+                       const struct userdiff_funcname *pe = &drv->funcname;
+                       xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
+                       opt->priv = &xecfg;
+               }
+       }
+
        while (left) {
                char *eol, ch;
                int hit;
@@ -711,6 +727,9 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                return 1;
        }
 
+       xdiff_clear_find_func(&xecfg);
+       opt->priv = NULL;
+
        /* NEEDSWORK:
         * The real "grep -c foo *.c" gives many "bar.c:0" lines,
         * which feels mostly useless but sometimes useful.  Maybe