Adds "basic", "extended", "fixed", and "perl" settings to the grep.extendedRegexp configuration option which set "--basic-regexp", "--extended-regexp", "--fixed-strings", and "--perl-regexp" options by default respectively. For the purposes of backwards compatibility, "extended" is equivalent to "true". --- Documentation/config.txt | 6 ++- Documentation/git-grep.txt | 6 ++- builtin/grep.c | 95 ++++++++++++++++++++++++---------------- grep.h | 8 ++++ t/t7810-grep.sh | 105 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 40 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt index a95e5a4..67d9f24 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1211,7 +1211,11 @@ grep.lineNumber:: If set to true, enable '-n' option by default. grep.extendedRegexp:: - If set to true, enable '--extended-regexp' option by default. + Sets the default matching behavior. This option can be set to a + boolean value or one of 'basic', 'extended', 'fixed', or 'perl' + which will enable the '--basic-regexp', '--extended-regexp', + '--fixed-strings' or '--perl-regexp' options accordingly. The value + of 'true' is equivalent to 'extended'. gpg.program:: Use this custom program instead of "gpg" found on $PATH when diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index 3bec036..100328f 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -43,7 +43,11 @@ grep.lineNumber:: If set to true, enable '-n' option by default. grep.extendedRegexp:: - If set to true, enable '--extended-regexp' option by default. + Sets the default matching behavior. This option can be set to a + boolean value or one of 'basic', 'extended', 'fixed', or 'perl' + which will enable the '--basic-regexp', '--extended-regexp', + '--fixed-strings' or '--perl-regexp' options accordingly. The value + of 'true' is equivalent to 'extended'. OPTIONS diff --git a/builtin/grep.c b/builtin/grep.c index 29adb0a..249fc7d 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -260,6 +260,55 @@ static int wait_all(void) } #endif +static int parse_pattern_type_arg(const char *opt, const char *arg) +{ + switch (git_config_maybe_bool(opt, arg)) { + case 1: + return GREP_PATTERN_TYPE_ERE; + case 0: + return GREP_PATTERN_TYPE_UNSPECIFIED; + default: + if (!strcmp(arg, "basic")) + return GREP_PATTERN_TYPE_BRE; + else if (!strcmp(arg, "extended")) + return GREP_PATTERN_TYPE_ERE; + else if (!strcmp(arg, "fixed")) + return GREP_PATTERN_TYPE_FIXED; + else if (!strcmp(arg, "perl")) + return GREP_PATTERN_TYPE_PCRE; + die("bad %s argument: %s", opt, arg); + } +} + +static void grep_pattern_type_options(const int pattern_type, void *cb) +{ + struct grep_opt *opt = cb; + + switch (pattern_type) { + case GREP_PATTERN_TYPE_BRE: + opt->fixed = 0; + opt->pcre = 0; + opt->regflags &= ~REG_EXTENDED; + break; + + case GREP_PATTERN_TYPE_ERE: + opt->fixed = 0; + opt->pcre = 0; + opt->regflags |= REG_EXTENDED; + break; + + case GREP_PATTERN_TYPE_FIXED: + opt->fixed = 1; + opt->pcre = 0; + break; + + case GREP_PATTERN_TYPE_PCRE: + opt->fixed = 0; + opt->pcre = 1; + break; + } +} + static int grep_config(const char *var, const char *value, void *cb) { struct grep_opt *opt = cb; @@ -269,10 +318,7 @@ static int grep_config(const char *var, const char *value, void *cb) return -1; if (!strcmp(var, "grep.extendedregexp")) { - if (git_config_bool(var, value)) - opt->regflags |= REG_EXTENDED; - else - opt->regflags &= ~REG_EXTENDED; + grep_pattern_type_options(parse_pattern_type_arg(var, value), opt); return 0; } @@ -669,14 +715,7 @@ 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; + int pattern_type = GREP_PATTERN_TYPE_UNSPECIFIED; struct option options[] = { OPT_BOOLEAN(0, "cached", &cached, @@ -705,16 +744,16 @@ int cmd_grep(int argc, const char **argv, const char *prefix) OPT_GROUP(""), OPT_SET_INT('E', "extended-regexp", &pattern_type, "use extended POSIX regular expressions", - pattern_type_ere), + GREP_PATTERN_TYPE_ERE), OPT_SET_INT('G', "basic-regexp", &pattern_type, "use basic POSIX regular expressions (default)", - pattern_type_bre), + GREP_PATTERN_TYPE_BRE), OPT_SET_INT('F', "fixed-strings", &pattern_type, "interpret patterns as fixed strings", - pattern_type_fixed), + GREP_PATTERN_TYPE_FIXED), OPT_SET_INT('P', "perl-regexp", &pattern_type, "use Perl-compatible regular expressions", - pattern_type_pcre), + GREP_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), @@ -824,28 +863,8 @@ 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 */ - } + + grep_pattern_type_options(pattern_type, &opt); if (use_index && !startup_info->have_repository) /* die the same way as if we did it at the beginning */ diff --git a/grep.h b/grep.h index ed7de6b..eb844a0 100644 --- a/grep.h +++ b/grep.h @@ -58,6 +58,14 @@ enum grep_expr_node { GREP_NODE_OR }; +enum grep_pattern_type { + GREP_PATTERN_TYPE_UNSPECIFIED = 0, + GREP_PATTERN_TYPE_BRE, + GREP_PATTERN_TYPE_ERE, + GREP_PATTERN_TYPE_FIXED, + GREP_PATTERN_TYPE_PCRE +}; + struct grep_expr { enum grep_expr_node node; unsigned hit; diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index 523d041..c21cd61 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -250,6 +250,36 @@ do git -c grep.extendedRegexp=true grep "a+b*c" ab >actual && test_cmp expected actual ' + + test_expect_success "grep $L with grep.extendedRegexp=extended" ' + echo "ab:abc" >expected && + git -c grep.extendedregexp=extended grep "a+b*c" ab >actual && + test_cmp expected actual + ' + + test_expect_success "grep $L with grep.extendedRegexp=fixed" ' + echo "ab:abc" >expected && + git -c grep.extendedregexp=fixed grep "ab" ab >actual && + test_cmp expected actual + ' + + test_expect_success "grep $L with a valid regexp and grep.extendedRegexp=fixed " ' + test_must_fail git -c grep.extendedregexp=fixed grep "a*" ab + ' + + test_expect_success "grep $L with grep.extendedRegexp=basic" ' + { + echo "ab:a+b*c" + echo "ab:a+bc" + echo "ab:abc" + } >expected && + git -c grep.extendedregexp=basic grep "a*" ab >actual && + test_cmp expected actual + ' + + test_expect_success "grep $L with a valid regexp and grep.extendedRegexp=basic " ' + test_must_fail git -c grep.extendedregexp=basic grep "a?" ab + ' done cat >expected <<EOF @@ -731,6 +761,81 @@ test_expect_success LIBPCRE 'grep -P pattern with grep.extendedRegexp=true' ' test_cmp expected actual ' +test_expect_success LIBPCRE 'grep -P pattern with grep.extendedRegexp=basic' ' + git -c grep.extendedregexp=basic \ + grep -P "\p{Ps}.*?\p{Pe}" hello.c >actual && + test_cmp expected actual +' + +test_expect_success LIBPCRE 'grep -P pattern with grep.extendedRegexp=extended' ' + git -c grep.extendedregexp=extended \ + grep -P "\p{Ps}.*?\p{Pe}" hello.c >actual && + test_cmp expected actual +' + +test_expect_success LIBPCRE 'grep -P pattern with grep.extendedRegexp=fixed' ' + git -c grep.extendedregexp=fixed \ + grep -P "\p{Ps}.*?\p{Pe}" hello.c >actual && + test_cmp expected actual +' + +test_expect_success LIBPCRE 'grep pattern with grep.extendedRegexp=perl' ' + git -c grep.extendedregexp=perl \ + grep "\p{Ps}.*?\p{Pe}" hello.c >actual && + test_cmp expected actual +' + +test_expect_success 'grep -E pattern with grep.extendedRegexp=perl' ' + test_must_fail git -c grep.extendedregexp=perl \ + grep -E "\p{Ps}.*?\p{Pe}" hello.c +' + +test_expect_success 'grep -G pattern with grep.extendedRegexp=perl' ' + test_must_fail git -c grep.extendedregexp=perl \ + grep -G "\p{Ps}.*?\p{Pe}" hello.c +' + +test_expect_success 'grep pattern with grep.extendedRegexp=fixed' ' + >empty && + test_must_fail git -c grep.extendedregexp=fixed \ + grep ".*" ab >actual && + test_cmp empty actual +' + +test_expect_success 'grep -E pattern with grep.extendedRegexp=basic' ' + { + echo "ab:a+b*c" + echo "ab:a+bc" + echo "ab:abc" + } >expected && + git -c grep.extendedregexp=basic \ + grep -E ".?" ab >actual && + test_cmp expected actual +' + +test_expect_success 'grep -E pattern with grep.extendedRegexp=fixed' ' + { + echo "ab:a+b*c" + echo "ab:a+bc" + echo "ab:abc" + } >expected && + git -c grep.extendedregexp=fixed \ + grep -E ".?" ab >actual && + test_cmp expected actual +' + +test_expect_success 'grep -G pattern with grep.extendedRegexp=fixed' ' + >empty && + test_must_fail git -c grep.extendedregexp=fixed \ + grep -G ".?" ab >actual && + test_cmp empty actual +' + +test_expect_success 'grep with grep.extendedRegexp=nonsense properly dies' ' + test_must_fail git -c grep.extendedregexp=nonsense \ + grep "\p{Ps}.*?\p{Pe}" hello.c +' + test_expect_success LIBPCRE 'grep -P -v pattern' ' { echo "ab:a+b*c" -- 1.7.11.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html