Add an option for using any HTTP authentication scheme, not only basic
[gitweb.git] / grep.c
diff --git a/grep.c b/grep.c
index 3a5c138476e5bc643656ec7a6e41da9fa3168969..bdadf2c0ccfafc18011beee3bc05754860392523 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)
@@ -40,6 +41,7 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
        int err;
 
        p->word_regexp = opt->word_regexp;
+       p->ignore_case = opt->ignore_case;
 
        if (opt->fixed || is_fixed(p->pattern))
                p->fixed = 1;
@@ -261,9 +263,15 @@ static void show_name(struct grep_opt *opt, const char *name)
        printf("%s%c", name, opt->null_following_name ? '\0' : '\n');
 }
 
-static int fixmatch(const char *pattern, char *line, regmatch_t *match)
+
+static int fixmatch(const char *pattern, char *line, int ignore_case, regmatch_t *match)
 {
-       char *hit = strstr(line, pattern);
+       char *hit;
+       if (ignore_case)
+               hit = strcasestr(line, pattern);
+       else
+               hit = strstr(line, pattern);
+
        if (!hit) {
                match->rm_so = match->rm_eo = -1;
                return REG_NOMATCH;
@@ -325,7 +333,7 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
 
  again:
        if (p->fixed)
-               hit = !fixmatch(p->pattern, bol, pmatch);
+               hit = !fixmatch(p->pattern, bol, p->ignore_case, pmatch);
        else
                hit = !regexec(&p->regexp, bol, 1, pmatch, eflags);
 
@@ -490,18 +498,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 +539,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 +568,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 +593,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 +625,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 +642,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 +734,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