[PATCH] built-in "git grep" (git grip) - quickfix
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:25
Subsystem:
the rest · Maintainer:
Linus Torvalds
Junio C Hamano [off-list ref] writes:
Right now, it does not understand and/or obey many options grep should accept, and the pattern matcher using POSIX.2 regex seems to be excruciatingly slow...
I forgot to say that unlike the shell script version you need to give -e in front of the pattern with this version because of the way the option parser is structured. Obviously this needs to be fixed for usability's sake. But I seem to have managed to fix the "excruciatingly slow" part trivially. regexec() is not re.match() but re.search(), and there is no point looking at each character on the line. Here is a patch. -- >8 --
diff --git a/builtin-grep.c b/builtin-grep.c
index adcdbaa..6230f44 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c@@ -42,26 +42,18 @@ static int grep_buffer(struct grep_opt * while (left) { regmatch_t pmatch[10]; - int flags = 0; - char *eol, *cp, ch; + char *eol, ch; eol = end_of_line(bol, &left); ch = *eol; *eol = 0; - for (cp = bol; cp < eol; cp++) { - int status = regexec(&opt->regexp, cp, - ARRAY_SIZE(pmatch), pmatch, - flags); - if (status == REG_NOMATCH) - flags |= REG_NOTBOL; - else if (status == 0) { - /* Hit at this line */ - printf("%s:", name); - if (opt->linenum) - printf("%d:", lno); - printf("%.*s\n", eol-bol, bol); - hit = 1; - break; - } + if (!regexec(&opt->regexp, bol, + ARRAY_SIZE(pmatch), pmatch, 0)) { + /* Hit at this line */ + printf("%s:", name); + if (opt->linenum) + printf("%d:", lno); + printf("%.*s\n", eol-bol, bol); + hit = 1; } *eol = ch; bol = eol + 1;