[PATCH/RFC 1/2] grep: add "basic", "extended", "fixed", and "perl" to grep.extendedRegexp

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]