]> rtime.felk.cvut.cz Git - git.git/blobdiff - grep.c
grep: use memmem() for fixed string search
[git.git] / grep.c
diff --git a/grep.c b/grep.c
index 2a8e879e88854f940a20216d3b202aed71efabd5..c3affb6caa45d1fe037a4ddfa0456cdd991e5859 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -329,14 +329,15 @@ static void show_name(struct grep_opt *opt, const char *name)
        opt->output(opt, opt->null_following_name ? "\0" : "\n", 1);
 }
 
-
-static int fixmatch(const char *pattern, char *line, int ignore_case, regmatch_t *match)
+static int fixmatch(const char *pattern, char *line, char *eol,
+                   int ignore_case, regmatch_t *match)
 {
        char *hit;
+
        if (ignore_case)
                hit = strcasestr(line, pattern);
        else
-               hit = strstr(line, pattern);
+               hit = memmem(line, eol - line, pattern, strlen(pattern));
 
        if (!hit) {
                match->rm_so = match->rm_eo = -1;
@@ -399,7 +400,7 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
 
  again:
        if (p->fixed)
-               hit = !fixmatch(p->pattern, bol, p->ignore_case, pmatch);
+               hit = !fixmatch(p->pattern, bol, eol, p->ignore_case, pmatch);
        else
                hit = !regexec(&p->regexp, bol, 1, pmatch, eflags);
 
@@ -725,9 +726,10 @@ static int look_ahead(struct grep_opt *opt,
                int hit;
                regmatch_t m;
 
-               if (p->fixed)
-                       hit = !fixmatch(p->pattern, bol, p->ignore_case, &m);
-               else {
+               if (p->fixed) {
+                       hit = !fixmatch(p->pattern, bol, bol + *left_p,
+                                       p->ignore_case, &m);
+               } else {
 #ifdef REG_STARTEND
                        m.rm_so = 0;
                        m.rm_eo = *left_p;
@@ -873,6 +875,12 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                        count++;
                        if (opt->status_only)
                                return 1;
+                       if (opt->name_only) {
+                               show_name(opt, name);
+                               return 1;
+                       }
+                       if (opt->count)
+                               goto next_line;
                        if (binary_match_only) {
                                opt->output(opt, "Binary file ", 12);
                                output_color(opt, name, strlen(name),
@@ -880,22 +888,14 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                                opt->output(opt, " matches\n", 9);
                                return 1;
                        }
-                       if (opt->name_only) {
-                               show_name(opt, name);
-                               return 1;
-                       }
                        /* Hit at this line.  If we haven't shown the
                         * pre-context lines, we would need to show them.
-                        * When asked to do "count", this still show
-                        * the context which is nonsense, but the user
-                        * deserves to get that ;-).
                         */
                        if (opt->pre_context)
                                show_pre_context(opt, name, buf, bol, lno);
                        else if (opt->funcname)
                                show_funcname_line(opt, name, buf, bol, lno);
-                       if (!opt->count)
-                               show_line(opt, bol, eol, name, lno, ':');
+                       show_line(opt, bol, eol, name, lno, ':');
                        last_hit = lno;
                }
                else if (last_hit &&
@@ -939,6 +939,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                output_sep(opt, ':');
                snprintf(buf, sizeof(buf), "%u\n", count);
                opt->output(opt, buf, strlen(buf));
+               return 1;
        }
        return !!last_hit;
 }