grep: add a grep.patternType configuration setting
The grep.extendedRegexp configuration setting enables the -E flag on grep by default but there are no equivalents for the -G, -F and -P flags. Rather than adding an additional setting for grep.fooRegexp for current and future pattern matching options, add a grep.patternType setting that can accept appropriate values for modifying the default grep pattern matching behavior. The current values are "basic", "extended", "fixed", "perl" and "default" for setting -G, -E, -F, -P and the default behavior respectively. When grep.patternType is set to a value other than "default", the grep.extendedRegexp setting is ignored. The value of "default" restores the current default behavior, including the grep.extendedRegexp behavior. Signed-off-by: J Smith <dark.panda@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
0e4c8822e9
commit
84befcd0a4
@ -1196,8 +1196,16 @@ gitweb.snapshot::
|
||||
grep.lineNumber::
|
||||
If set to true, enable '-n' option by default.
|
||||
|
||||
grep.patternType::
|
||||
Set the default matching behavior. Using a value of 'basic', 'extended',
|
||||
'fixed', or 'perl' will enable the '--basic-regexp', '--extended-regexp',
|
||||
'--fixed-strings', or '--perl-regexp' option accordingly, while the
|
||||
value 'default' will return to the default matching behavior.
|
||||
|
||||
grep.extendedRegexp::
|
||||
If set to true, enable '--extended-regexp' option by default.
|
||||
If set to true, enable '--extended-regexp' option by default. This
|
||||
option is ignored when the 'grep.patternType' option is set to a value
|
||||
other than 'default'.
|
||||
|
||||
gpg.program::
|
||||
Use this custom program instead of "gpg" found on $PATH when
|
||||
|
@ -42,8 +42,16 @@ CONFIGURATION
|
||||
grep.lineNumber::
|
||||
If set to true, enable '-n' option by default.
|
||||
|
||||
grep.patternType::
|
||||
Set the default matching behavior. Using a value of 'basic', 'extended',
|
||||
'fixed', or 'perl' will enable the '--basic-regexp', '--extended-regexp',
|
||||
'--fixed-strings', or '--perl-regexp' option accordingly, while the
|
||||
value 'default' will return to the default matching behavior.
|
||||
|
||||
grep.extendedRegexp::
|
||||
If set to true, enable '--extended-regexp' option by default.
|
||||
If set to true, enable '--extended-regexp' option by default. This
|
||||
option is ignored when the 'grep.patternType' option is set to a value
|
||||
other than 'default'.
|
||||
|
||||
|
||||
OPTIONS
|
||||
|
112
builtin/grep.c
112
builtin/grep.c
@ -260,6 +260,53 @@ static int wait_all(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int parse_pattern_type_arg(const char *opt, const char *arg)
|
||||
{
|
||||
if (!strcmp(arg, "default"))
|
||||
return GREP_PATTERN_TYPE_UNSPECIFIED;
|
||||
else 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, struct grep_opt *opt)
|
||||
{
|
||||
switch (pattern_type) {
|
||||
case GREP_PATTERN_TYPE_UNSPECIFIED:
|
||||
/* fall through */
|
||||
|
||||
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;
|
||||
opt->regflags &= ~REG_EXTENDED;
|
||||
break;
|
||||
|
||||
case GREP_PATTERN_TYPE_PCRE:
|
||||
opt->fixed = 0;
|
||||
opt->pcre = 1;
|
||||
opt->regflags &= ~REG_EXTENDED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int grep_config(const char *var, const char *value, void *cb)
|
||||
{
|
||||
struct grep_opt *opt = cb;
|
||||
@ -270,12 +317,17 @@ static int grep_config(const char *var, const char *value, void *cb)
|
||||
|
||||
if (!strcmp(var, "grep.extendedregexp")) {
|
||||
if (git_config_bool(var, value))
|
||||
opt->regflags |= REG_EXTENDED;
|
||||
opt->extended_regexp_option = 1;
|
||||
else
|
||||
opt->regflags &= ~REG_EXTENDED;
|
||||
opt->extended_regexp_option = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(var, "grep.patterntype")) {
|
||||
opt->pattern_type_option = parse_pattern_type_arg(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(var, "grep.linenumber")) {
|
||||
opt->linenum = git_config_bool(var, value);
|
||||
return 0;
|
||||
@ -669,14 +721,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_arg = GREP_PATTERN_TYPE_UNSPECIFIED;
|
||||
|
||||
struct option options[] = {
|
||||
OPT_BOOLEAN(0, "cached", &cached,
|
||||
@ -703,18 +748,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_SET_INT('E', "extended-regexp", &pattern_type,
|
||||
OPT_SET_INT('E', "extended-regexp", &pattern_type_arg,
|
||||
"use extended POSIX regular expressions",
|
||||
pattern_type_ere),
|
||||
OPT_SET_INT('G', "basic-regexp", &pattern_type,
|
||||
GREP_PATTERN_TYPE_ERE),
|
||||
OPT_SET_INT('G', "basic-regexp", &pattern_type_arg,
|
||||
"use basic POSIX regular expressions (default)",
|
||||
pattern_type_bre),
|
||||
OPT_SET_INT('F', "fixed-strings", &pattern_type,
|
||||
GREP_PATTERN_TYPE_BRE),
|
||||
OPT_SET_INT('F', "fixed-strings", &pattern_type_arg,
|
||||
"interpret patterns as fixed strings",
|
||||
pattern_type_fixed),
|
||||
OPT_SET_INT('P', "perl-regexp", &pattern_type,
|
||||
GREP_PATTERN_TYPE_FIXED),
|
||||
OPT_SET_INT('P', "perl-regexp", &pattern_type_arg,
|
||||
"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),
|
||||
@ -799,6 +844,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
||||
opt.header_tail = &opt.header_list;
|
||||
opt.regflags = REG_NEWLINE;
|
||||
opt.max_depth = -1;
|
||||
opt.pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED;
|
||||
opt.extended_regexp_option = 0;
|
||||
|
||||
strcpy(opt.color_context, "");
|
||||
strcpy(opt.color_filename, "");
|
||||
@ -824,28 +871,13 @@ 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 (pattern_type_arg != GREP_PATTERN_TYPE_UNSPECIFIED)
|
||||
grep_pattern_type_options(pattern_type_arg, &opt);
|
||||
else if (opt.pattern_type_option != GREP_PATTERN_TYPE_UNSPECIFIED)
|
||||
grep_pattern_type_options(opt.pattern_type_option, &opt);
|
||||
else if (opt.extended_regexp_option)
|
||||
grep_pattern_type_options(GREP_PATTERN_TYPE_ERE, &opt);
|
||||
|
||||
if (use_index && !startup_info->have_repository)
|
||||
/* die the same way as if we did it at the beginning */
|
||||
|
10
grep.h
10
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;
|
||||
@ -103,6 +111,8 @@ struct grep_opt {
|
||||
int max_depth;
|
||||
int funcname;
|
||||
int funcbody;
|
||||
int extended_regexp_option;
|
||||
int pattern_type_option;
|
||||
char color_context[COLOR_MAXLEN];
|
||||
char color_filename[COLOR_MAXLEN];
|
||||
char color_function[COLOR_MAXLEN];
|
||||
|
181
t/t7810-grep.sh
181
t/t7810-grep.sh
@ -250,6 +250,84 @@ do
|
||||
git -c grep.extendedRegexp=true grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success "grep $L with grep.patterntype=basic" '
|
||||
echo "ab:a+bc" >expected &&
|
||||
git -c grep.patterntype=basic grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success "grep $L with grep.patterntype=extended" '
|
||||
echo "ab:abc" >expected &&
|
||||
git -c grep.patterntype=extended grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success "grep $L with grep.patterntype=fixed" '
|
||||
echo "ab:a+b*c" >expected &&
|
||||
git -c grep.patterntype=fixed grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success LIBPCRE "grep $L with grep.patterntype=perl" '
|
||||
echo "ab:a+b*c" >expected &&
|
||||
git -c grep.patterntype=perl grep "a\x{2b}b\x{2a}c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success "grep $L with grep.patternType=default and grep.extendedRegexp=true" '
|
||||
echo "ab:abc" >expected &&
|
||||
git \
|
||||
-c grep.patternType=default \
|
||||
-c grep.extendedRegexp=true \
|
||||
grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=default" '
|
||||
echo "ab:abc" >expected &&
|
||||
git \
|
||||
-c grep.extendedRegexp=true \
|
||||
-c grep.patternType=default \
|
||||
grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep $L with grep.patternType=extended and grep.extendedRegexp=false' '
|
||||
echo "ab:abc" >expected &&
|
||||
git \
|
||||
-c grep.patternType=extended \
|
||||
-c grep.extendedRegexp=false \
|
||||
grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep $L with grep.patternType=basic and grep.extendedRegexp=true' '
|
||||
echo "ab:a+bc" >expected &&
|
||||
git \
|
||||
-c grep.patternType=basic \
|
||||
-c grep.extendedRegexp=true \
|
||||
grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep $L with grep.extendedRegexp=false and grep.patternType=extended' '
|
||||
echo "ab:abc" >expected &&
|
||||
git \
|
||||
-c grep.extendedRegexp=false \
|
||||
-c grep.patternType=extended \
|
||||
grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep $L with grep.extendedRegexp=true and grep.patternType=basic' '
|
||||
echo "ab:a+bc" >expected &&
|
||||
git \
|
||||
-c grep.extendedRegexp=true \
|
||||
-c grep.patternType=basic \
|
||||
grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
done
|
||||
|
||||
cat >expected <<EOF
|
||||
@ -772,44 +850,147 @@ test_expect_success 'grep -G invalidpattern properly dies ' '
|
||||
test_must_fail git grep -G "a["
|
||||
'
|
||||
|
||||
test_expect_success 'grep invalidpattern properly dies with grep.patternType=basic' '
|
||||
test_must_fail git -c grep.patterntype=basic grep "a["
|
||||
'
|
||||
|
||||
test_expect_success 'grep -E invalidpattern properly dies ' '
|
||||
test_must_fail git grep -E "a["
|
||||
'
|
||||
|
||||
test_expect_success 'grep invalidpattern properly dies with grep.patternType=extended' '
|
||||
test_must_fail git -c grep.patterntype=extended grep "a["
|
||||
'
|
||||
|
||||
test_expect_success LIBPCRE 'grep -P invalidpattern properly dies ' '
|
||||
test_must_fail git grep -P "a["
|
||||
'
|
||||
|
||||
test_expect_success LIBPCRE 'grep invalidpattern properly dies with grep.patternType=perl' '
|
||||
test_must_fail git -c grep.patterntype=perl grep "a["
|
||||
'
|
||||
|
||||
test_expect_success 'grep -G -E -F pattern' '
|
||||
echo "ab:a+b*c" >expected &&
|
||||
git grep -G -E -F "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep pattern with grep.patternType=basic, =extended, =fixed' '
|
||||
echo "ab:a+b*c" >expected &&
|
||||
git \
|
||||
-c grep.patterntype=basic \
|
||||
-c grep.patterntype=extended \
|
||||
-c grep.patterntype=fixed \
|
||||
grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep -E -F -G pattern' '
|
||||
echo "ab:a+bc" >expected &&
|
||||
git grep -E -F -G "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep pattern with grep.patternType=extended, =fixed, =basic' '
|
||||
echo "ab:a+bc" >expected &&
|
||||
git \
|
||||
-c grep.patterntype=extended \
|
||||
-c grep.patterntype=fixed \
|
||||
-c grep.patterntype=basic \
|
||||
grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep -F -G -E pattern' '
|
||||
echo "ab:abc" >expected &&
|
||||
git grep -F -G -E "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =extended' '
|
||||
echo "ab:abc" >expected &&
|
||||
git \
|
||||
-c grep.patterntype=fixed \
|
||||
-c grep.patterntype=basic \
|
||||
-c grep.patterntype=extended \
|
||||
grep "a+b*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep -G -F -P -E pattern' '
|
||||
>empty &&
|
||||
test_must_fail git grep -G -F -P -E "a\x{2b}b\x{2a}c" ab >actual &&
|
||||
test_cmp empty actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =perl, =extended' '
|
||||
>empty &&
|
||||
test_must_fail git \
|
||||
-c grep.patterntype=fixed \
|
||||
-c grep.patterntype=basic \
|
||||
-c grep.patterntype=perl \
|
||||
-c grep.patterntype=extended \
|
||||
grep "a\x{2b}b\x{2a}c" ab >actual &&
|
||||
test_cmp empty actual
|
||||
'
|
||||
|
||||
test_expect_success LIBPCRE 'grep -G -F -E -P pattern' '
|
||||
echo "ab:a+b*c" >expected &&
|
||||
git grep -G -F -E -P "a\x{2b}b\x{2a}c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success LIBPCRE 'grep pattern with grep.patternType=fixed, =basic, =extended, =perl' '
|
||||
echo "ab:a+b*c" >expected &&
|
||||
git \
|
||||
-c grep.patterntype=fixed \
|
||||
-c grep.patterntype=basic \
|
||||
-c grep.patterntype=extended \
|
||||
-c grep.patterntype=perl \
|
||||
grep "a\x{2b}b\x{2a}c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success LIBPCRE 'grep -P pattern with grep.patternType=fixed' '
|
||||
echo "ab:a+b*c" >expected &&
|
||||
git \
|
||||
-c grep.patterntype=fixed \
|
||||
grep -P "a\x{2b}b\x{2a}c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep -F pattern with grep.patternType=basic' '
|
||||
echo "ab:a+b*c" >expected &&
|
||||
git \
|
||||
-c grep.patterntype=basic \
|
||||
grep -F "*c" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep -G pattern with grep.patternType=fixed' '
|
||||
{
|
||||
echo "ab:a+b*c"
|
||||
echo "ab:a+bc"
|
||||
} >expected &&
|
||||
git \
|
||||
-c grep.patterntype=fixed \
|
||||
grep -G "a+b" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'grep -E pattern with grep.patternType=fixed' '
|
||||
{
|
||||
echo "ab:a+b*c"
|
||||
echo "ab:a+bc"
|
||||
echo "ab:abc"
|
||||
} >expected &&
|
||||
git \
|
||||
-c grep.patterntype=fixed \
|
||||
grep -E "a+" ab >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_config() {
|
||||
git config "$1" "$2" &&
|
||||
test_when_finished "git config --unset $1"
|
||||
|
Loading…
Reference in New Issue
Block a user