git-grep: do not die upon -F/-P when grep.extendedRegexp is set.
authorJunio C Hamano <gitster@pobox.com>
Tue, 10 May 2011 01:48:36 +0000 (18:48 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 10 May 2011 05:53:16 +0000 (22:53 -0700)
The previous one made "git grep -P" fail when grep.extendedRegexp is
enabled. That is a no-starter. The option on the command line should
just make the command ignore the configured default. The handling of "-F"
in the existing code has the same problem.

Instead of saying -G/-F/-E/-P incompatible with each other, just allow
the last one win. That way, you can have "[alias] gr = grep -P" and
use Pcre for everyday work e.g. "git gr ':i?foo'", and append -G to the
aliased command line to override it e.g. "git gr -G '[Ff][Oo][Oo]'".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/grep.c
index 8f2602653ee1e017c326a726aa485dd17abd03df..298f763b702f80c4f8d9f37b3356d36b2b8da32f 100644 (file)
@@ -753,6 +753,15 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
        int i;
        int dummy;
        int use_index = 1;
+       enum {
+               pattern_type_unspecified = 0,
+               pattern_type_bre,
+               pattern_type_ere,
+               pattern_type_fixed,
+               pattern_type_pcre,
+       };
+       int pattern_type = pattern_type_unspecified;
+
        struct option options[] = {
                OPT_BOOLEAN(0, "cached", &cached,
                        "search in index instead of in the work tree"),
@@ -774,15 +783,18 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                        "descend at most <depth> levels", PARSE_OPT_NONEG,
                        NULL, 1 },
                OPT_GROUP(""),
-               OPT_BIT('E', "extended-regexp", &opt.regflags,
-                       "use extended POSIX regular expressions", REG_EXTENDED),
-               OPT_NEGBIT('G', "basic-regexp", &opt.regflags,
-                       "use basic POSIX regular expressions (default)",
-                       REG_EXTENDED),
-               OPT_BOOLEAN('F', "fixed-strings", &opt.fixed,
-                       "interpret patterns as fixed strings"),
-               OPT_BOOLEAN('P', "perl-regexp", &opt.pcre,
-                               "use Perl-compatible regular expressions"),
+               OPT_SET_INT('E', "extended-regexp", &pattern_type,
+                           "use extended POSIX regular expressions",
+                           pattern_type_ere),
+               OPT_SET_INT('G', "basic-regexp", &pattern_type,
+                           "use basic POSIX regular expressions (default)",
+                           pattern_type_bre),
+               OPT_SET_INT('F', "fixed-strings", &pattern_type,
+                           "interpret patterns as fixed strings",
+                           pattern_type_fixed),
+               OPT_SET_INT('P', "perl-regexp", &pattern_type,
+                           "use Perl-compatible regular expressions",
+                           pattern_type_pcre),
                OPT_GROUP(""),
                OPT_BOOLEAN('n', "line-number", &opt.linenum, "show line numbers"),
                OPT_NEGBIT('h', NULL, &opt.pathname, "don't show filenames", 1),
@@ -888,6 +900,28 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                             PARSE_OPT_KEEP_DASHDASH |
                             PARSE_OPT_STOP_AT_NON_OPTION |
                             PARSE_OPT_NO_INTERNAL_HELP);
+       switch (pattern_type) {
+       case pattern_type_fixed:
+               opt.fixed = 1;
+               opt.pcre = 0;
+               break;
+       case pattern_type_bre:
+               opt.fixed = 0;
+               opt.pcre = 0;
+               opt.regflags &= ~REG_EXTENDED;
+               break;
+       case pattern_type_ere:
+               opt.fixed = 0;
+               opt.pcre = 0;
+               opt.regflags |= REG_EXTENDED;
+               break;
+       case pattern_type_pcre:
+               opt.fixed = 0;
+               opt.pcre = 1;
+               break;
+       default:
+               break; /* nothing */
+       }
 
        if (use_index && !startup_info->have_repository)
                /* die the same way as if we did it at the beginning */
@@ -925,12 +959,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 
        if (!opt.pattern_list)
                die(_("no pattern given."));
-       if (opt.regflags != REG_NEWLINE && opt.pcre)
-               die(_("cannot mix --extended-regexp and --perl-regexp"));
        if (!opt.fixed && opt.ignore_case)
                opt.regflags |= REG_ICASE;
-       if ((opt.regflags != REG_NEWLINE || opt.pcre) && opt.fixed)
-               die(_("cannot mix --fixed-strings and regexp"));
 
 #ifndef NO_PTHREADS
        if (online_cpus() == 1 || !grep_threads_ok(&opt))