builtin-grep: -F (--fixed-strings)
authorJunio C Hamano <junkio@cox.net>
Wed, 10 May 2006 01:28:41 +0000 (18:28 -0700)
committerJunio C Hamano <junkio@cox.net>
Wed, 10 May 2006 01:29:35 +0000 (18:29 -0700)
Signed-off-by: Junio C Hamano <junkio@cox.net>
Documentation/git-grep.txt
builtin-grep.c

index 56b683a..74102b7 100644 (file)
@@ -12,7 +12,7 @@ SYNOPSIS
 'git-grep' [--cached]
           [-a | --text] [-I] [-i | --ignore-case] [-w | --word-regexp]
           [-v | --invert-match]
-          [-E | --extended-regexp]  [-G | --basic-regexp]
+          [-E | --extended-regexp] [-G | --basic-regexp] [-F | --fixed-strings]
           [-n] [-l | --files-with-matches] [-L | --files-without-match]
           [-c | --count]
           [-A <post-context>] [-B <pre-context>] [-C <context>]
index 52ac521..fead356 100644 (file)
@@ -98,6 +98,7 @@ struct grep_opt {
        unsigned unmatch_name_only:1;
        unsigned count:1;
        unsigned word_regexp:1;
+       unsigned fixed:1;
 #define GREP_BINARY_DEFAULT    0
 #define GREP_BINARY_NOMATCH    1
 #define GREP_BINARY_TEXT       2
@@ -179,6 +180,20 @@ static int buffer_is_binary(const char *ptr, unsigned long size)
        return 0;
 }
 
+static int fixmatch(const char *pattern, char *line, regmatch_t *match)
+{
+       char *hit = strstr(line, pattern);
+       if (!hit) {
+               match->rm_so = match->rm_eo = -1;
+               return REG_NOMATCH;
+       }
+       else {
+               match->rm_so = hit - line;
+               match->rm_eo = match->rm_so + strlen(pattern);
+               return 0;
+       }
+}
+
 static int grep_buffer(struct grep_opt *opt, const char *name,
                       char *buf, unsigned long size)
 {
@@ -224,9 +239,14 @@ static int grep_buffer(struct grep_opt *opt, const char *name,
                *eol = 0;
 
                for (p = opt->pattern_list; p; p = p->next) {
-                       regex_t *exp = &p->regexp;
-                       hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
-                                      pmatch, 0);
+                       if (!opt->fixed) {
+                               regex_t *exp = &p->regexp;
+                               hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
+                                              pmatch, 0);
+                       }
+                       else {
+                               hit = !fixmatch(p->pattern, bol, pmatch);
+                       }
 
                        if (hit && opt->word_regexp) {
                                /* Match beginning must be either
@@ -549,6 +569,11 @@ int cmd_grep(int argc, const char **argv, char **envp)
                        opt.regflags |= REG_EXTENDED;
                        continue;
                }
+               if (!strcmp("-F", arg) ||
+                   !strcmp("--fixed-strings", arg)) {
+                       opt.fixed = 1;
+                       continue;
+               }
                if (!strcmp("-G", arg) ||
                    !strcmp("--basic-regexp", arg)) {
                        opt.regflags &= ~REG_EXTENDED;
@@ -674,7 +699,10 @@ int cmd_grep(int argc, const char **argv, char **envp)
 
        if (!opt.pattern_list)
                die("no pattern given.");
-       compile_patterns(&opt);
+       if ((opt.regflags != REG_NEWLINE) && opt.fixed)
+               die("cannot mix --fixed-strings and regexp");
+       if (!opt.fixed)
+               compile_patterns(&opt);
 
        /* Check revs and then paths */
        for (i = 1; i < argc; i++) {