PCRE v1 improvements & PCRE v2 support
Subsystems (2)
v3 cover PCRE v1 improvements & PCRE v2 support
Sorry about the high volume sending. I thought I wouldn't have time to work on v3 for a while, but here it is a day later. I promise to hold off on further sending for a bit.
This, unlike v2, addresses all the outstanding comments the series had. Most importantly I added a patch at the end to remove the concurrent support for v1 & v2 of the library as Jeff & Junio suggested.
See the v2 coverletter in <[email protected]> for changes since v1, changes since v2 noted below:
Ævar Arnfjörð Bjarmason (18):
grep: amend submodule recursion test in preparation for rx engine
testing
grep: add tests for grep pattern types being passed to submodules
grep: submodule-related case statements should die if new fields are
added
I thought there was a bug in v2 still where submodule grepping wouldn't properly pass along e.g. -c grep.patternType=pcre2, this turned out to not be the case since we pass -c options to subprocesses via the GIT_CONFIG_PARAMETERS env var, which I didn't know about.
But in preparing to fix that I wrote these tests which improve on some blind spots in the tests Brandon initially added for the submodule grep. It's part of this series because it would conflict with subsequent patches if sent stand-alone, but is otherwise unrelated.
grep: remove redundant regflags assignment under PCRE Makefile & configure: reword outdated comment about PCRE
No changes.
grep: add a test for backreferences in PCRE patterns
s/PCRE/LIBPCRE/ for the prereq check. That's changed later, but this patch didn't work properly stand-alone, error introduced in earlier v1-era rebasing.
log: add exhaustive tests for pattern style options & config
log: add -P as a synonym for --perl-regexp
No changes.
grep & rev-list doc: stop promising libpcre for --perl-regexp
I've reworded these docs to make even weaker promises about what's a "Perl-compatible regular expression". As noted in the commit message the motivation is that maybe in the future we'd like to provide -P via some entirely different library, e.g. Intel's hyperscan. This leaves that door open without breaking existing promises in the documentation.
grep: make grep.patternType=[pcre|pcre1] a synonym for "perl"
Now with tests for recursive submodule grepping.
test-lib: rename the LIBPCRE prerequisite to PCRE
Now with s/LIBPCRE/PCRE/ back for the s/PCRE/LIBPCRE/ change noted earlier.
grep: change the internal PCRE macro names to be PCRE1
grep: change the internal PCRE code & header names to be PCRE1
perf: add a performance comparison test of grep -E and -P
grep: add support for the PCRE v1 JIT API
No changes.
grep: add support for PCRE v2
Fix one s/LIBPCREDIR/LIBPCRE2DIR/ in a ./configure notice which I missed & tests & minor changes for recursive submodule grepping.
grep: remove support concurrent use of both PCRE v1 & v2
NEW: Removes grep.patternType=[pcre|pcre1|pcre2] & makes trying to compile git with both v1 & v2 an error, but either one will work, with v1 being the default still.
After writing this up & seeing what the change is I also agree that it's a good idea to apply this. It makes the user-facing docs simpler, but also the various tests which previously had to worry about [pcre|pcre1|pcre2] which now just test "perl".
Makefile & configure: make PCRE v2 the default PCRE implementation
NEW: This changes the default PCRE implementation to v2, and makes USE_LIBPCRE mean USE_LIBPCRE2, but USE_LIBPCRE1 is still available.
I originally wrote this as something to keep for some future submission, but come to think of it I can't see why it shouldn't be applied.
The v2 PCRE is stable & end-user compatible, all this change does is change the default, someone building a new git is likely to also have packaged PCRE v2 sometime in the last 2 years since it was released, and if not they can choose to use the legacy v2 library by making the trivial s/USE_LIBPCRE/USE_LIBPCRE1/ change, or package up PCRE v2.
Documentation/git-grep.txt | 7 +- Documentation/rev-list-options.txt | 9 +- Makefile | 39 +++++-- builtin/grep.c | 4 + configure.ac | 81 +++++++++++--- grep.c | 214 ++++++++++++++++++++++++++++++------ grep.h | 32 +++++- revision.c | 2 +- t/README | 4 +- t/perf/p7820-grep-engines.sh | 25 +++++ t/t4202-log.sh | 86 ++++++++++++++- t/t7810-grep.sh | 41 ++++--- t/t7812-grep-icase-non-ascii.sh | 4 +- t/t7813-grep-icase-iso.sh | 11 +- t/t7814-grep-recurse-submodules.sh | 215 +++++++++++++++++++++++-------------- t/test-lib.sh | 3 +- 16 files changed, 608 insertions(+), 169 deletions(-) create mode 100755 t/perf/p7820-grep-engines.sh
Signature · 1 line
2.11.0
PATCH v3 1/18 grep: amend submodule recursion test in preparation for rx engine testing
Amend the submodule recursion test added in commit 0281e487fd ("grep:
optionally recurse into submodules", 2016-12-16) to prepare it for subsequent tests of whether it passes along the grep.patternType to the submodule greps.
This is just the result of searching & replacing:
foobar -> (1|2)d(3|4)
foo -> (1|2)
bar -> (3|4)Currently there's no tests for whether e.g. -P or -E is correctly passed along, tests for that will be added in a follow-up change, but first add content to the tests which will match differently under different regex engines.
Reuse the pattern established in an earlier commit of mine in this series ("log: add exhaustive tests for pattern style options & config", 2017-04-07). The pattern "(.|.)[\d]" will match this content differently under fixed/basic/extended & perl.
--- t/t7814-grep-recurse-submodules.sh | 166 ++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 83 deletions(-)
t/t7814-grep-recurse-submodules.sh +83 -83
@@ -9,13 +9,13 @@ submodules. . ./test-lib.sh test_expect_success 'setup directory structure and submodule' ' - echo "foobar" >a && + echo "(1|2)d(3|4)" >a && mkdir b && - echo "bar" >b/b && + echo "(3|4)" >b/b && git add a b && git commit -m "add a and b" && git init submodule && - echo "foobar" >submodule/a && + echo "(1|2)d(3|4)" >submodule/a && git -C submodule add a && git -C submodule commit -m "add a" && git submodule add ./submodule &&
@@ -24,18 +24,18 @@ test_expect_success 'setup directory structure and submodule' ' test_expect_success 'grep correctly finds patterns in a submodule' ' cat >expect <<-\EOF && - a:foobar - b/b:bar - submodule/a:foobar + a:(1|2)d(3|4) + b/b:(3|4) + submodule/a:(1|2)d(3|4) EOF - git grep -e "bar" --recurse-submodules >actual && + git grep -e "(3|4)" --recurse-submodules >actual && test_cmp expect actual ' test_expect_success 'grep and basic pathspecs' ' cat >expect <<-\EOF && - submodule/a:foobar + submodule/a:(1|2)d(3|4) EOF git grep -e. --recurse-submodules -- submodule >actual &&
@@ -44,7 +44,7 @@ test_expect_success 'grep and basic pathspecs' ' test_expect_success 'grep and nested submodules' ' git init submodule/sub && - echo "foobar" >submodule/sub/a && + echo "(1|2)d(3|4)" >submodule/sub/a && git -C submodule/sub add a && git -C submodule/sub commit -m "add a" && git -C submodule submodule add ./sub &&
@@ -54,117 +54,117 @@ test_expect_success 'grep and nested submodules' ' git commit -m "updated submodule" && cat >expect <<-\EOF && - a:foobar - b/b:bar - submodule/a:foobar - submodule/sub/a:foobar + a:(1|2)d(3|4) + b/b:(3|4) + submodule/a:(1|2)d(3|4) + submodule/sub/a:(1|2)d(3|4) EOF - git grep -e "bar" --recurse-submodules >actual && + git grep -e "(3|4)" --recurse-submodules >actual && test_cmp expect actual ' test_expect_success 'grep and multiple patterns' ' cat >expect <<-\EOF && - a:foobar - submodule/a:foobar - submodule/sub/a:foobar + a:(1|2)d(3|4) + submodule/a:(1|2)d(3|4) + submodule/sub/a:(1|2)d(3|4) EOF - git grep -e "bar" --and -e "foo" --recurse-submodules >actual && + git grep -e "(3|4)" --and -e "(1|2)d" --recurse-submodules >actual && test_cmp expect actual ' test_expect_success 'grep and multiple patterns' ' cat >expect <<-\EOF && - b/b:bar + b/b:(3|4) EOF - git grep -e "bar" --and --not -e "foo" --recurse-submodules >actual && + git grep -e "(3|4)" --and --not -e "(1|2)d" --recurse-submodules >actual && test_cmp expect actual ' test_expect_success 'basic grep tree' ' cat >expect <<-\EOF && - HEAD:a:foobar - HEAD:b/b:bar - HEAD:submodule/a:foobar - HEAD:submodule/sub/a:foobar + HEAD:a:(1|2)d(3|4) + HEAD:b/b:(3|4) + HEAD:submodule/a:(1|2)d(3|4) + HEAD:submodule/sub/a:(1|2)d(3|4) EOF - git grep -e "bar" --recurse-submodules HEAD >actual && + git grep -e "(3|4)" --recurse-submodules HEAD >actual && test_cmp expect actual ' test_expect_success 'grep tree HEAD^' ' cat >expect <<-\EOF && - HEAD^:a:foobar - HEAD^:b/b:bar - HEAD^:submodule/a:foobar + HEAD^:a:(1|2)d(3|4) + HEAD^:b/b:(3|4) + HEAD^:submodule/a:(1|2)d(3|4) EOF - git grep -e "bar" --recurse-submodules HEAD^ >actual && + git grep -e "(3|4)" --recurse-submodules HEAD^ >actual && test_cmp expect actual ' test_expect_success 'grep tree HEAD^^' ' cat >expect <<-\EOF && - HEAD^^:a:foobar - HEAD^^:b/b:bar + HEAD^^:a:(1|2)d(3|4) + HEAD^^:b/b:(3|4) EOF - git grep -e "bar" --recurse-submodules HEAD^^ >actual && + git grep -e "(3|4)" --recurse-submodules HEAD^^ >actual && test_cmp expect actual ' test_expect_success 'grep tree and pathspecs' ' cat >expect <<-\EOF && - HEAD:submodule/a:foobar - HEAD:submodule/sub/a:foobar + HEAD:submodule/a:(1|2)d(3|4) + HEAD:submodule/sub/a:(1|2)d(3|4) EOF - git grep -e "bar" --recurse-submodules HEAD -- submodule >actual && + git grep -e "(3|4)" --recurse-submodules HEAD -- submodule >actual && test_cmp expect actual ' test_expect_success 'grep tree and pathspecs' ' cat >expect <<-\EOF && - HEAD:submodule/a:foobar - HEAD:submodule/sub/a:foobar + HEAD:submodule/a:(1|2)d(3|4) + HEAD:submodule/sub/a:(1|2)d(3|4) EOF - git grep -e "bar" --recurse-submodules HEAD -- "submodule*a" >actual && + git grep -e "(3|4)" --recurse-submodules HEAD -- "submodule*a" >actual && test_cmp expect actual ' test_expect_success 'grep tree and more pathspecs' ' cat >expect <<-\EOF && - HEAD:submodule/a:foobar + HEAD:submodule/a:(1|2)d(3|4) EOF - git grep -e "bar" --recurse-submodules HEAD -- "submodul?/a" >actual && + git grep -e "(3|4)" --recurse-submodules HEAD -- "submodul?/a" >actual && test_cmp expect actual ' test_expect_success 'grep tree and more pathspecs' ' cat >expect <<-\EOF && - HEAD:submodule/sub/a:foobar + HEAD:submodule/sub/a:(1|2)d(3|4) EOF - git grep -e "bar" --recurse-submodules HEAD -- "submodul*/sub/a" >actual && + git grep -e "(3|4)" --recurse-submodules HEAD -- "submodul*/sub/a" >actual && test_cmp expect actual ' test_expect_success !MINGW 'grep recurse submodule colon in name' ' git init parent && test_when_finished "rm -rf parent" && - echo "foobar" >"parent/fi:le" && + echo "(1|2)d(3|4)" >"parent/fi:le" && git -C parent add "fi:le" && git -C parent commit -m "add fi:le" && git init "su:b" && test_when_finished "rm -rf su:b" && - echo "foobar" >"su:b/fi:le" && + echo "(1|2)d(3|4)" >"su:b/fi:le" && git -C "su:b" add "fi:le" && git -C "su:b" commit -m "add fi:le" &&
@@ -172,30 +172,30 @@ test_expect_success !MINGW 'grep recurse submodule colon in name' ' git -C parent commit -m "add submodule" && cat >expect <<-\EOF && - fi:le:foobar - su:b/fi:le:foobar + fi:le:(1|2)d(3|4) + su:b/fi:le:(1|2)d(3|4) EOF - git -C parent grep -e "foobar" --recurse-submodules >actual && + git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules >actual && test_cmp expect actual && cat >expect <<-\EOF && - HEAD:fi:le:foobar - HEAD:su:b/fi:le:foobar + HEAD:fi:le:(1|2)d(3|4) + HEAD:su:b/fi:le:(1|2)d(3|4) EOF - git -C parent grep -e "foobar" --recurse-submodules HEAD >actual && + git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules HEAD >actual && test_cmp expect actual ' test_expect_success 'grep history with moved submoules' ' git init parent && test_when_finished "rm -rf parent" && - echo "foobar" >parent/file && + echo "(1|2)d(3|4)" >parent/file && git -C parent add file && git -C parent commit -m "add file" && git init sub && test_when_finished "rm -rf sub" && - echo "foobar" >sub/file && + echo "(1|2)d(3|4)" >sub/file && git -C sub add file && git -C sub commit -m "add file" &&
@@ -203,82 +203,82 @@ test_expect_success 'grep history with moved submoules' ' git -C parent commit -m "add submodule" && cat >expect <<-\EOF && - dir/sub/file:foobar - file:foobar + dir/sub/file:(1|2)d(3|4) + file:(1|2)d(3|4) EOF - git -C parent grep -e "foobar" --recurse-submodules >actual && + git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules >actual && test_cmp expect actual && git -C parent mv dir/sub sub-moved && git -C parent commit -m "moved submodule" && cat >expect <<-\EOF && - file:foobar - sub-moved/file:foobar + file:(1|2)d(3|4) + sub-moved/file:(1|2)d(3|4) EOF - git -C parent grep -e "foobar" --recurse-submodules >actual && + git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules >actual && test_cmp expect actual && cat >expect <<-\EOF && - HEAD^:dir/sub/file:foobar - HEAD^:file:foobar + HEAD^:dir/sub/file:(1|2)d(3|4) + HEAD^:file:(1|2)d(3|4) EOF - git -C parent grep -e "foobar" --recurse-submodules HEAD^ >actual && + git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules HEAD^ >actual && test_cmp expect actual ' test_expect_success 'grep using relative path' ' test_when_finished "rm -rf parent sub" && git init sub && - echo "foobar" >sub/file && + echo "(1|2)d(3|4)" >sub/file && git -C sub add file && git -C sub commit -m "add file" && git init parent && - echo "foobar" >parent/file && + echo "(1|2)d(3|4)" >parent/file && git -C parent add file && mkdir parent/src && - echo "foobar" >parent/src/file2 && + echo "(1|2)d(3|4)" >parent/src/file2 && git -C parent add src/file2 && git -C parent submodule add ../sub && git -C parent commit -m "add files and submodule" && # From top works cat >expect <<-\EOF && - file:foobar - src/file2:foobar - sub/file:foobar + file:(1|2)d(3|4) + src/file2:(1|2)d(3|4) + sub/file:(1|2)d(3|4) EOF - git -C parent grep --recurse-submodules -e "foobar" >actual && + git -C parent grep --recurse-submodules -e "(1|2)d(3|4)" >actual && test_cmp expect actual && # Relative path to top cat >expect <<-\EOF && - ../file:foobar - file2:foobar - ../sub/file:foobar + ../file:(1|2)d(3|4) + file2:(1|2)d(3|4) + ../sub/file:(1|2)d(3|4) EOF - git -C parent/src grep --recurse-submodules -e "foobar" -- .. >actual && + git -C parent/src grep --recurse-submodules -e "(1|2)d(3|4)" -- .. >actual && test_cmp expect actual && # Relative path to submodule cat >expect <<-\EOF && - ../sub/file:foobar + ../sub/file:(1|2)d(3|4) EOF - git -C parent/src grep --recurse-submodules -e "foobar" -- ../sub >actual && + git -C parent/src grep --recurse-submodules -e "(1|2)d(3|4)" -- ../sub >actual && test_cmp expect actual ' test_expect_success 'grep from a subdir' ' test_when_finished "rm -rf parent sub" && git init sub && - echo "foobar" >sub/file && + echo "(1|2)d(3|4)" >sub/file && git -C sub add file && git -C sub commit -m "add file" && git init parent && mkdir parent/src && - echo "foobar" >parent/src/file && + echo "(1|2)d(3|4)" >parent/src/file && git -C parent add src/file && git -C parent submodule add ../sub src/sub && git -C parent submodule add ../sub sub &&
@@ -286,19 +286,19 @@ test_expect_success 'grep from a subdir' ' # Verify grep from root works cat >expect <<-\EOF && - src/file:foobar - src/sub/file:foobar - sub/file:foobar + src/file:(1|2)d(3|4) + src/sub/file:(1|2)d(3|4) + sub/file:(1|2)d(3|4) EOF - git -C parent grep --recurse-submodules -e "foobar" >actual && + git -C parent grep --recurse-submodules -e "(1|2)d(3|4)" >actual && test_cmp expect actual && # Verify grep from a subdir works cat >expect <<-\EOF && - file:foobar - sub/file:foobar + file:(1|2)d(3|4) + sub/file:(1|2)d(3|4) EOF - git -C parent/src grep --recurse-submodules -e "foobar" >actual && + git -C parent/src grep --recurse-submodules -e "(1|2)d(3|4)" >actual && test_cmp expect actual '
Signature · 1 line
2.11.0
Re: [PATCH v3 01/18] grep: amend submodule recursion test in preparation for rx engine testing
Quoted 16 lines · Ævar Arnfjörð Bjarmason
Amend the submodule recursion test added in commit
0281e487fd("grep:
optionally recurse into submodules", 2016-12-16) to prepare it for subsequent tests of whether it passes along the grep.patternType to the submodule greps.This is just the result of searching & replacing:
foobar -> (1|2)d(3|4) foo -> (1|2) bar -> (3|4)Currently there's no tests for whether e.g. -P or -E is correctly passed along, tests for that will be added in a follow-up change, but first add content to the tests which will match differently under different regex engines.
Quoted 6 lines
Reuse the pattern established in an earlier commit of mine in this series ("log: add exhaustive tests for pattern style options & config", 2017-04-07). The pattern "(.|.)[\d]" will match this content differently under fixed/basic/extended & perl.
Signed-off-by Ævar Arnfjörð Bjarmason <[email protected]>
Looks good.
Signature · 1 line
Brandon Williams
PATCH v3 2/18 grep: add tests for grep pattern types being passed to submodules
In reply to Ævar Arnfjörð BjarmasonAdd testing for grep pattern types being correctly passed to submodules. The pattern "(.|.)[\d]" matches differently under fixed (not at all), and then matches different lines under basic/extended & perl regular expressions, so this change asserts that the pattern type is passed along correctly.
--- t/t7814-grep-recurse-submodules.sh | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
t/t7814-grep-recurse-submodules.sh +49 -0
@@ -313,4 +313,53 @@ test_incompatible_with_recurse_submodules () test_incompatible_with_recurse_submodules --untracked test_incompatible_with_recurse_submodules --no-index +test_expect_success 'grep --recurse-submodules should pass the pattern type along' ' + # Fixed + test_must_fail git grep -F --recurse-submodules -e "(.|.)[\d]" && + test_must_fail git -c grep.patternType=fixed grep --recurse-submodules -e "(.|.)[\d]" && + + # Basic + git grep -G --recurse-submodules -e "(.|.)[\d]" >actual && + cat >expect <<-\EOF && + a:(1|2)d(3|4) + submodule/a:(1|2)d(3|4) + submodule/sub/a:(1|2)d(3|4) + EOF + test_cmp expect actual && + git -c grep.patternType=basic grep --recurse-submodules -e "(.|.)[\d]" >actual && + test_cmp expect actual && + + # Extended + git grep -E --recurse-submodules -e "(.|.)[\d]" >actual && + cat >expect <<-\EOF && + .gitmodules:[submodule "submodule"] + .gitmodules: path = submodule + .gitmodules: url = ./submodule + a:(1|2)d(3|4) + submodule/.gitmodules:[submodule "sub"] + submodule/a:(1|2)d(3|4) + submodule/sub/a:(1|2)d(3|4) + EOF + test_cmp expect actual && + git -c grep.patternType=extended grep --recurse-submodules -e "(.|.)[\d]" >actual && + test_cmp expect actual && + git -c grep.extendedRegexp=true grep --recurse-submodules -e "(.|.)[\d]" >actual && + test_cmp expect actual && + + # Perl + if test_have_prereq PCRE + then + git grep -P --recurse-submodules -e "(.|.)[\d]" >actual && + cat >expect <<-\EOF && + a:(1|2)d(3|4) + b/b:(3|4) + submodule/a:(1|2)d(3|4) + submodule/sub/a:(1|2)d(3|4) + EOF + test_cmp expect actual && + git -c grep.patternType=perl grep --recurse-submodules -e "(.|.)[\d]" >actual && + test_cmp expect actual + fi +' + test_done
Signature · 1 line
2.11.0
PATCH v3 3/18 grep: submodule-related case statements should die if new fields are added
In reply to Ævar Arnfjörð BjarmasonChange two case statements added in commit 0281e487fd ("grep:
optionally recurse into submodules", 2016-12-16) so that they die if new GREP_PATTERN_* enum fields are added without updating them.
These case statements currently check for an exhaustive list of fields, but if a new field is added it's easy to introduce a bug here where the code will start subtly doing the wrong thing, e.g. if a new pattern type is added we'll fall through to GREP_PATTERN_TYPE_UNSPECIFIED, i.e. the "basic" POSIX regular expressions.
This should arguably be done for the switch(opt->binary) case-statement as well, but isn't trivial to add since that code isn't currently working with an exhaustive list.
--- builtin/grep.c | 4 ++++ 1 file changed, 4 insertions(+)
builtin/grep.c +4 -0
@@ -495,6 +495,8 @@ static void compile_submodule_options(const struct grep_opt *opt,break ;case GREP_PATTERN_TYPE_UNSPECIFIED :break ; +default : +die ("BUG: Added a new grep pattern type without updating switch statement" ); } for (pattern = opt->pattern_list; pattern != NULL;
@@ -515,6 +517,8 @@ static void compile_submodule_options(const struct grep_opt *opt,case GREP_PATTERN_BODY :case GREP_PATTERN_HEAD :break ; +default : +die ("BUG: Added a new grep token type without updating case statement" ); } }
Signature · 1 line
2.11.0
Re: [PATCH v3 03/18] grep: submodule-related case statements should die if new fields are added
Quoted 11 lines · Ævar Arnfjörð Bjarmason
Change two case statements added in commit
0281e487fd("grep:
optionally recurse into submodules", 2016-12-16) so that they die if new GREP_PATTERN_* enum fields are added without updating them.These case statements currently check for an exhaustive list of fields, but if a new field is added it's easy to introduce a bug here where the code will start subtly doing the wrong thing, e.g. if a new pattern type is added we'll fall through to
GREP_PATTERN_TYPE_UNSPECIFIED, i.e. the "basic" POSIX regular expressions.
Quoted 3 lines
This should arguably be done for the
switch(opt->binary)case-statement as well, but isn't trivial to add since that code isn't currently working with an exhaustive list.
I was under the impression that the code wouldn't compile if there is a missing enum field in the switch statement. Does it instead silently fall through? I would choose not compiling over a die statement that may not be caught during the development of a new series.
Quoted 31 lines
Signed-off-by Ævar Arnfjörð Bjarmason <[email protected]>--- builtin/grep.c | 4 ++++ 1 file changed, 4 insertions(+)builtin/grep.c +4
-0@@ -495,6 +495,8 @@ static void compile_submodule_options(const struct grep_opt *opt,break ;case GREP_PATTERN_TYPE_UNSPECIFIED :break ; +default : +die ("BUG: Added a new grep pattern type without updating switch statement" ); } for (pattern = opt->pattern_list; pattern != NULL;@@ -515,6 +517,8 @@ static void compile_submodule_options(const struct grep_opt *opt,case GREP_PATTERN_BODY :case GREP_PATTERN_HEAD :break ; +default : +die ("BUG: Added a new grep token type without updating case statement" ); } }Signature · 1 line
2.11.0
Signature · 1 line
Brandon Williams
Re: [PATCH v3 03/18] grep: submodule-related case statements should die if new fields are added
Quoted 12 lines · Brandon Williams
Quoted 11 lines · Ævar Arnfjörð Bjarmason
Change two case statements added in commit
0281e487fd("grep:
optionally recurse into submodules", 2016-12-16) so that they die if new GREP_PATTERN_* enum fields are added without updating them.These case statements currently check for an exhaustive list of fields, but if a new field is added it's easy to introduce a bug here where the code will start subtly doing the wrong thing, e.g. if a new pattern type is added we'll fall through to
GREP_PATTERN_TYPE_UNSPECIFIED, i.e. the "basic" POSIX regular expressions.
Quoted 8 lines
Quoted 3 lines
This should arguably be done for the
switch(opt->binary)case-statement as well, but isn't trivial to add since that code isn't currently working with an exhaustive list.I was under the impression that the code wouldn't compile if there is a missing enum field in the switch statement. Does it instead silently fall through? I would choose not compiling over a die statement that may not be caught during the development of a new series.
Usually -Wswitch would catch this, but the variable in question is declared as an int. The original pattern_type_arg variable is an int because we pass its address via OPT_SET_INT().
We could make the argument to compile_submodule_options() an enum, but then we get an implicit cast when we pass the int (which could fail at runtime). Yech. I'm not sure if there's a good and easy solution.
-Peff
PATCH v3 4/18 grep: remove redundant regflags assignment under PCRE
In reply to Ævar Arnfjörð BjarmasonRemove a redundant assignment to the "regflags" variable. This variable is only used for POSIX regular expression matching, not when the PCRE library is used.
This redundant assignment was added as a result of copy/paste programming in commit 84befcd0a4 ("grep: add a grep.patternType configuration setting", 2012-08-03). That commit modified already working code in commit cca2c172e0 ("git-grep: do not die upon -F/-P when grep.extendedRegexp is set.", 2011-05-09) which didn't assign to regflags when under PCRE.
Revert back to that behavior, more to reduce "wait this is used under PCRE how?" confusion when reading the code, than to to save ourselves trivial CPU cycles by removing one assignment.
--- grep.c | 1 - 1 file changed, 1 deletion(-)
grep.c +0 -1
@@ -197,7 +197,6 @@ static void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, stcase GREP_PATTERN_TYPE_PCRE : opt->fixed =0 ; opt->pcre =1 ; - opt->regflags &= ~REG_EXTENDED ;break ; } }
Signature · 1 line
2.11.0
PATCH v3 5/18 Makefile & configure: reword outdated comment about PCRE
In reply to Ævar Arnfjörð BjarmasonReword an outdated comment which suggests that only git-grep can use PCRE.
This comment was added back when PCRE support was initially added in commit 63e7e9d8b6 ("git-grep: Learn PCRE", 2011-05-09), and was true at the time.
It hasn't been telling the full truth since git-log learned to use PCRE with --grep in commit 727b6fc3ed ("log --grep: accept --basic-regexp and --perl-regexp", 2012-10-03), and more importantly is likely to get more inaccurate over time as more use is made of PCRE in other areas.
Reword it to be more future-proof, and to more clearly explain that this enables user-initiated runtime behavior.
Copy/pasting this so much in configure.ac is lame, these Makefile-like flags aren't even used by autoconf, just the corresponding --with[out]-* options. But copy/pasting the comments that make sense for the Makefile to configure.ac where they make less sence is the pattern everything else follows in that file. I'm not going to war against that as part of this change, just following the existing pattern.
--- Makefile | 6 ++++-- configure.ac | 12 ++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-)
Makefile +4 -2
@@ -24,8 +24,10 @@ all:: # Define NO_OPENSSL environment variable if you do not have OpenSSL. # This also implies BLK_SHA1. # -# Define USE_LIBPCRE if you have and want to use libpcre. git-grep will be -# able to use Perl-compatible regular expressions. +# Define USE_LIBPCRE if you have and want to use libpcre. Various +# commands such as log and grep offer runtime options to use +# Perl-compatible regular expressions instead of standard or extended +# POSIX regular expressions. # # Define LIBPCREDIR=/foo/bar if your libpcre header and library files are in # /foo/bar/include and /foo/bar/lib directories.
configure.ac +8 -4
@@ -250,8 +250,10 @@ AS_HELP_STRING([--with-openssl],[use OpenSSL library (default is YES)]) AS_HELP_STRING([], [ARG can be prefix for openssl library and headers]), GIT_PARSE_WITH([openssl])) -# Define USE_LIBPCRE if you have and want to use libpcre. git-grep will be -# able to use Perl-compatible regular expressions. +# Define USE_LIBPCRE if you have and want to use libpcre. Various +# commands such as log and grep offer runtime options to use +# Perl-compatible regular expressions instead of standard or extended +# POSIX regular expressions. # # Define LIBPCREDIR=/foo/bar if your libpcre header and library files are in # /foo/bar/include and /foo/bar/lib directories.
@@ -499,8 +501,10 @@ GIT_CONF_SUBST([NEEDS_SSL_WITH_CRYPTO]) GIT_CONF_SUBST([NO_OPENSSL]) # -# Define USE_LIBPCRE if you have and want to use libpcre. git-grep will be -# able to use Perl-compatible regular expressions. +# Define USE_LIBPCRE if you have and want to use libpcre. Various +# commands such as log and grep offer runtime options to use +# Perl-compatible regular expressions instead of standard or extended +# POSIX regular expressions. # if test -n "$USE_LIBPCRE"; then
Signature · 1 line
2.11.0
PATCH v3 6/18 grep: add a test for backreferences in PCRE patterns
In reply to Ævar Arnfjörð BjarmasonAdd a test for backreferences such as (.)\1 in PCRE patterns. This test ensures that the PCRE_NO_AUTO_CAPTURE option isn't turned on. Before this change turning it on would break these sort of patterns, but wouldn't break any tests.
--- t/t7810-grep.sh | 7 +++++++ 1 file changed, 7 insertions(+)
t/t7810-grep.sh +7 -0
@@ -1102,6 +1102,13 @@ test_expect_success LIBPCRE 'grep -P -w pattern' ' test_cmp expected actual ' +test_expect_success LIBPCRE 'grep -P backreferences work (the PCRE NO_AUTO_CAPTURE flag is not set)' ' + git grep -P -h "(?P<one>.)(?P=one)" hello_world >actual && + test_cmp hello_world actual && + git grep -P -h "(.)\1" hello_world >actual && + test_cmp hello_world actual +' + test_expect_success 'grep -G invalidpattern properly dies ' ' test_must_fail git grep -G "a[" '
Signature · 1 line
2.11.0
PATCH v3 7/18 log: add exhaustive tests for pattern style options & config
In reply to Ævar Arnfjörð BjarmasonAdd exhaustive tests for how the different grep.patternType options & the corresponding command-line options affect git-log.
Before this change it was possible to patch revision.c so that the --basic-regexp option was synonymous with --extended-regexp, and --perl-regexp wasn't recognized at all, and still have 100% of the test suite pass.
This was because the first test being modified here, added in commit 34a4ae55b2 ("log --grep: use the same helper to set -E/-F options as "git grep"", 2012-10-03), didn't actually check whether we'd enabled extended regular expressions as distinct from re-toggling non-fixed string support.
Fix that by changing the pattern to a pattern that'll only match if --extended-regexp option is provided, but won't match under the default --basic-regexp option.
Other potential regressions were possible since there were no tests for the rest of the combinations of grep.patternType configuration toggles & corresponding git-log command-line options. Add exhaustive tests for those.
The patterns being passed to fixed/basic/extended/PCRE are carefully crafted to return the wrong thing if the grep engine were to pick any other matching method than the one it's told to use.
--- t/t4202-log.sh | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-)
t/t4202-log.sh +76 -1
@@ -262,7 +262,23 @@ test_expect_success 'log --grep -i' ' test_expect_success 'log -F -E --grep=<ere> uses ere' ' echo second >expect && - git log -1 --pretty="tformat:%s" -F -E --grep=s.c.nd >actual && + git log -1 --pretty="tformat:%s" -F -E --grep="(s).c.nd" >actual && + test_cmp expect actual +' + +test_expect_success LIBPCRE 'log -F -E --perl-regexp --grep=<pcre> uses PCRE' ' + test_when_finished "rm -rf num_commits" && + git init num_commits && + ( + cd num_commits && + test_commit 1d && + test_commit 2e + ) && + echo 2e >expect && + git -C num_commits log -1 --pretty="tformat:%s" -F -E --perl-regexp --grep="[\d]" >actual && + test_cmp expect actual && + echo 1d >expect && + git -C num_commits log -1 --pretty="tformat:%s" -F -E --grep="[\d]" >actual && test_cmp expect actual '
@@ -280,6 +296,65 @@ test_expect_success 'log with grep.patternType configuration and command line' ' test_cmp expect actual ' +test_expect_success 'log with various grep.patternType configurations & command-lines' ' + git init pattern-type && + ( + cd pattern-type && + test_commit 1 file A && + test_commit "(1|2)" file B && + + echo "(1|2)" >expect.fixed && + cp expect.fixed expect.basic && + cp expect.fixed expect.extended && + cp expect.fixed expect.perl && + + git -c grep.patternType=fixed log --pretty=tformat:%s \ + --grep="(1|2)" >actual.fixed && + git -c grep.patternType=basic log --pretty=tformat:%s \ + --grep="(.|.)" >actual.basic && + git -c grep.patternType=extended log --pretty=tformat:%s \ + --grep="\|2" >actual.extended && + if test_have_prereq LIBPCRE + then + git -c grep.patternType=perl log --pretty=tformat:%s \ + --grep="[\d]\|" >actual.perl + fi && + test_cmp expect.fixed actual.fixed && + test_cmp expect.basic actual.basic && + test_cmp expect.extended actual.extended && + if test_have_prereq LIBPCRE + then + test_cmp expect.perl actual.perl + fi && + + git log --pretty=tformat:%s -F \ + --grep="(1|2)" >actual.fixed.short-arg && + git log --pretty=tformat:%s -E \ + --grep="\|2" >actual.extended.short-arg && + test_cmp expect.fixed actual.fixed.short-arg && + test_cmp expect.extended actual.extended.short-arg && + + git log --pretty=tformat:%s --fixed-strings \ + --grep="(1|2)" >actual.fixed.long-arg && + git log --pretty=tformat:%s --basic-regexp \ + --grep="(.|.)" >actual.basic.long-arg && + git log --pretty=tformat:%s --extended-regexp \ + --grep="\|2" >actual.extended.long-arg && + if test_have_prereq LIBPCRE + then + git log --pretty=tformat:%s --perl-regexp \ + --grep="[\d]\|" >actual.perl.long-arg + fi && + test_cmp expect.fixed actual.fixed.long-arg && + test_cmp expect.basic actual.basic.long-arg && + test_cmp expect.extended actual.extended.long-arg && + if test_have_prereq LIBPCRE + then + test_cmp expect.perl actual.perl.long-arg + fi + ) +' + cat > expect <<EOF * Second * sixth
Signature · 1 line
2.11.0
PATCH v3 8/18 log: add -P as a synonym for --perl-regexp
In reply to Ævar Arnfjörð BjarmasonAdd a short -P option as a synonym for the longer --perl-regexp, for consistency with the options the corresponding grep invocations accept.
This was intentionally omitted in commit 727b6fc3ed ("log --grep:
accept --basic-regexp and --perl-regexp", 2012-10-03) for unspecified future use.
Since nothing has come along in over 4 1/2 years that's wanted to use it, it's more valuable to make it consistent with "grep" than to keep it open for future use, and to avoid the confusion of -P meaning different things for grep & log, as is the case with the -G option.
As noted in the aforementioned commit the --basic-regexp option can't have a corresponding -G argument, as the log command already uses that for -G<regex>.
--- Documentation/rev-list-options.txt | 1 + revision.c | 2 +- t/t4202-log.sh | 9 +++++++++ 3 files changed, 11 insertions(+), 1 deletion(-)
Documentation/rev-list-options.txt +1 -0
@@ -91,6 +91,7 @@ endif::git-rev-list[] Consider the limiting patterns to be fixed strings (don't interpret pattern as a regular expression). +-P:: --perl-regexp:: Consider the limiting patterns to be Perl-compatible regular expressions. Requires libpcre to be compiled in.
revision.c +1 -1
@@ -1995,7 +1995,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **argDIFF_OPT_SET (&revs->diffopt,PICKAXE_IGNORE_CASE ); }else if (!strcmp (arg,"--fixed-strings" ) || !strcmp (arg,"-F" )) { revs->grep_filter.pattern_type_option =GREP_PATTERN_TYPE_FIXED ; - }else if (!strcmp (arg,"--perl-regexp" )) { + }else if (!strcmp (arg,"--perl-regexp" ) || !strcmp (arg,"-P" )) { revs->grep_filter.pattern_type_option =GREP_PATTERN_TYPE_PCRE ; }else if (!strcmp (arg,"--all-match" )) { revs->grep_filter.all_match =1 ;
t/t4202-log.sh +9 -0
@@ -331,8 +331,17 @@ test_expect_success 'log with various grep.patternType configurations & command- --grep="(1|2)" >actual.fixed.short-arg && git log --pretty=tformat:%s -E \ --grep="\|2" >actual.extended.short-arg && + if test_have_prereq PCRE + then + git log --pretty=tformat:%s -P \ + --grep="[\d]\|" >actual.perl.short-arg + fi && test_cmp expect.fixed actual.fixed.short-arg && test_cmp expect.extended actual.extended.short-arg && + if test_have_prereq PCRE + then + test_cmp expect.perl actual.perl.short-arg + fi && git log --pretty=tformat:%s --fixed-strings \ --grep="(1|2)" >actual.fixed.long-arg &&
Signature · 1 line
2.11.0
PATCH v3 9/18 grep & rev-list doc: stop promising libpcre for --perl-regexp
In reply to Ævar Arnfjörð BjarmasonStop promising in our grep & rev-list options documentation that we're always going to be using libpcre when given the --perl-regexp option.
Instead talk about using "Perl-compatible regular expressions" and using these types of patterns using "a compile-time dependency".
Saying "libpcre" strongly suggests that we might be talking about libpcre.so, which is always going to be v1. This change is part of a series to add support for libpcre2 which comes with v2 of PCRE.
In the future we might use some completely unrelated library to provide perl-compatible regular expression support. By wording the documentation differently and not promising any specific version of PCRE or ever PCRE at all we have more wiggle room to change the implementation.
--- Documentation/git-grep.txt | 7 +++++-- Documentation/rev-list-options.txt | 8 ++++++-- 2 files changed, 11 insertions(+), 4 deletions(-)
Documentation/git-grep.txt +5 -2
@@ -161,8 +161,11 @@ OPTIONS -P:: --perl-regexp:: - Use Perl-compatible regexp for patterns. Requires libpcre to be - compiled in. + Use Perl-compatible regular expressions for patterns. ++ +Support for these types of regular expressions is an optional +compile-time dependency. If Git wasn't compiled with support for them +providing this option will cause it to die. -F:: --fixed-strings::
Documentation/rev-list-options.txt +6 -2
@@ -93,8 +93,12 @@ endif::git-rev-list[] -P:: --perl-regexp:: - Consider the limiting patterns to be Perl-compatible regular expressions. - Requires libpcre to be compiled in. + Consider the limiting patterns to be Perl-compatible regular + expressions. ++ +Support for these types of regular expressions is an optional +compile-time dependency. If Git wasn't compiled with support for them +providing this option will cause it to die. --remove-empty:: Stop when a given path disappears from the tree.
Signature · 1 line
2.11.0
PATCH v3 10/18 grep: make grep.patternType=[pcre|pcre1] a synonym for "perl"
In reply to Ævar Arnfjörð BjarmasonMake the pattern types "pcre" & "pcre1" synonyms for the long-standing "perl" grep.patternType.
This change is part of a longer patch series to add pcre2 support to Git. It's nice to be able to performance test PCRE v1 v.s. v2 without having to recompile git, and doing that via grep.patternType makes sense.
However, just adding "pcre2" when we only have "perl" would be confusing, so start by adding a "pcre" & "pcre1" synonym.
In the future "perl" and "pcre" might be changed to default to "pcre2" instead of "pcre1", and depending on how Git is compiled the more specific "pcre1" or "pcre2" pattern types might produce an error.
--- Documentation/config.txt | 9 +++++++++ grep.c | 4 +++- t/t7810-grep.sh | 10 ++++++++++ t/t7814-grep-recurse-submodules.sh | 4 ++++ 4 files changed, 26 insertions(+), 1 deletion(-)
Documentation/config.txt +9 -0
@@ -1624,6 +1624,15 @@ grep.patternType:: '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. ++ +The 'pcre' and 'pcre1' values are synonyms for 'perl'. The other +values starting with 'pcre' are reserved for future use, e.g. if we'd +like to use 'pcre2' for the PCRE v2 library. ++ +In the future 'perl' and 'pcre' might become synonyms for some other +implementation or PCRE version, such as 'pcre2', while the more +specific 'pcre1' & 'pcre2' might throw errors depending on whether git +is compiled to include those libraries. grep.extendedRegexp:: If set to true, enable `--extended-regexp` option by default. This
grep.c +3 -1
@@ -60,7 +60,9 @@ static int parse_pattern_type_arg(const char *opt, const char *arg)return GREP_PATTERN_TYPE_ERE ; else if (!strcmp(arg, "fixed"))return GREP_PATTERN_TYPE_FIXED ; - else if (!strcmp(arg, "perl")) + else if (!strcmp(arg, "perl") || + !strcmp(arg, "pcre") || + !strcmp(arg, "pcre1"))return GREP_PATTERN_TYPE_PCRE ;die ("bad %s argument: %s" , opt, arg); }
t/t7810-grep.sh +10 -0
@@ -1512,4 +1512,14 @@ test_expect_success 'grep does not report i-t-a and assume unchanged with -L' ' test_cmp expected actual ' +test_expect_success LIBPCRE "grep with grep.patternType synonyms perl/pcre/pcre1" ' + echo "#include <stdio.h>" >expected && + git -c grep.patternType=perl grep -h --no-line-number "st(?=dio)" >actual && + test_cmp expected actual && + git -c grep.patternType=pcre grep -h --no-line-number "st(?=dio)" >actual && + test_cmp expected actual && + git -c grep.patternType=pcre1 grep -h --no-line-number "st(?=dio)" >actual && + test_cmp expected actual +' + test_done
t/t7814-grep-recurse-submodules.sh +4 -0
@@ -358,6 +358,10 @@ test_expect_success 'grep --recurse-submodules should pass the pattern type alon EOF test_cmp expect actual && git -c grep.patternType=perl grep --recurse-submodules -e "(.|.)[\d]" >actual && + test_cmp expect actual && + git -c grep.patternType=pcre grep --recurse-submodules -e "(.|.)[\d]" >actual && + test_cmp expect actual && + git -c grep.patternType=pcre1 grep --recurse-submodules -e "(.|.)[\d]" >actual && test_cmp expect actual fi '
Signature · 1 line
2.11.0
PATCH v3 11/18 test-lib: rename the LIBPCRE prerequisite to PCRE
In reply to Ævar Arnfjörð BjarmasonRename the LIBPCRE prerequisite to PCRE. This is for preparation for libpcre2 support, where having just "LIBPCRE" would be confusing as it implies v1 of the library.
None of these tests are incompatible between versions 1 & 2 of libpcre, it's less confusing to give them a more general name to make it clear that they work on both library versions.
--- t/README | 4 ++-- t/t4202-log.sh | 10 +++++----- t/t7810-grep.sh | 32 ++++++++++++++++---------------- t/t7812-grep-icase-non-ascii.sh | 4 ++-- t/t7813-grep-icase-iso.sh | 2 +- t/test-lib.sh | 2 +- 6 files changed, 27 insertions(+), 27 deletions(-)
t/README +2 -2
@@ -803,9 +803,9 @@ use these, and "test_set_prereq" for how to define your own. Test is not run by root user, and an attempt to write to an unwritable file is expected to fail correctly. - - LIBPCRE + - PCRE - Git was compiled with USE_LIBPCRE=YesPlease. Wrap any tests + Git was compiled with support for PCRE. Wrap any tests that use git-grep --perl-regexp or git-grep -P in these. - CASE_INSENSITIVE_FS
t/t4202-log.sh +5 -5
@@ -266,7 +266,7 @@ test_expect_success 'log -F -E --grep=<ere> uses ere' ' test_cmp expect actual ' -test_expect_success LIBPCRE 'log -F -E --perl-regexp --grep=<pcre> uses PCRE' ' +test_expect_success PCRE 'log -F -E --perl-regexp --grep=<pcre> uses PCRE' ' test_when_finished "rm -rf num_commits" && git init num_commits && (
@@ -314,7 +314,7 @@ test_expect_success 'log with various grep.patternType configurations & command- --grep="(.|.)" >actual.basic && git -c grep.patternType=extended log --pretty=tformat:%s \ --grep="\|2" >actual.extended && - if test_have_prereq LIBPCRE + if test_have_prereq PCRE then git -c grep.patternType=perl log --pretty=tformat:%s \ --grep="[\d]\|" >actual.perl
@@ -322,7 +322,7 @@ test_expect_success 'log with various grep.patternType configurations & command- test_cmp expect.fixed actual.fixed && test_cmp expect.basic actual.basic && test_cmp expect.extended actual.extended && - if test_have_prereq LIBPCRE + if test_have_prereq PCRE then test_cmp expect.perl actual.perl fi &&
@@ -349,7 +349,7 @@ test_expect_success 'log with various grep.patternType configurations & command- --grep="(.|.)" >actual.basic.long-arg && git log --pretty=tformat:%s --extended-regexp \ --grep="\|2" >actual.extended.long-arg && - if test_have_prereq LIBPCRE + if test_have_prereq PCRE then git log --pretty=tformat:%s --perl-regexp \ --grep="[\d]\|" >actual.perl.long-arg
@@ -357,7 +357,7 @@ test_expect_success 'log with various grep.patternType configurations & command- test_cmp expect.fixed actual.fixed.long-arg && test_cmp expect.basic actual.basic.long-arg && test_cmp expect.extended actual.extended.long-arg && - if test_have_prereq LIBPCRE + if test_have_prereq PCRE then test_cmp expect.perl actual.perl.long-arg fi
t/t7810-grep.sh +16 -16
@@ -275,7 +275,7 @@ do test_cmp expected actual ' - test_expect_success LIBPCRE "grep $L with grep.patterntype=perl" ' + test_expect_success PCRE "grep $L with grep.patterntype=perl" ' echo "${HC}ab:a+b*c" >expected && git -c grep.patterntype=perl grep "a\x{2b}b\x{2a}c" $H ab >actual && test_cmp expected actual
@@ -1053,12 +1053,12 @@ hello.c:int main(int argc, const char **argv) hello.c: printf("Hello world.\n"); EOF -test_expect_success LIBPCRE 'grep --perl-regexp pattern' ' +test_expect_success PCRE 'grep --perl-regexp pattern' ' git grep --perl-regexp "\p{Ps}.*?\p{Pe}" hello.c >actual && test_cmp expected actual ' -test_expect_success LIBPCRE 'grep -P pattern' ' +test_expect_success PCRE 'grep -P pattern' ' git grep -P "\p{Ps}.*?\p{Pe}" hello.c >actual && test_cmp expected actual '
@@ -1070,13 +1070,13 @@ test_expect_success 'grep pattern with grep.extendedRegexp=true' ' test_cmp empty actual ' -test_expect_success LIBPCRE 'grep -P pattern with grep.extendedRegexp=true' ' +test_expect_success PCRE 'grep -P pattern with grep.extendedRegexp=true' ' git -c grep.extendedregexp=true \ grep -P "\p{Ps}.*?\p{Pe}" hello.c >actual && test_cmp expected actual ' -test_expect_success LIBPCRE 'grep -P -v pattern' ' +test_expect_success PCRE 'grep -P -v pattern' ' { echo "ab:a+b*c" echo "ab:a+bc"
@@ -1085,7 +1085,7 @@ test_expect_success LIBPCRE 'grep -P -v pattern' ' test_cmp expected actual ' -test_expect_success LIBPCRE 'grep -P -i pattern' ' +test_expect_success PCRE 'grep -P -i pattern' ' cat >expected <<-EOF && hello.c: printf("Hello world.\n"); EOF
@@ -1093,7 +1093,7 @@ test_expect_success LIBPCRE 'grep -P -i pattern' ' test_cmp expected actual ' -test_expect_success LIBPCRE 'grep -P -w pattern' ' +test_expect_success PCRE 'grep -P -w pattern' ' { echo "hello_world:Hello world" echo "hello_world:HeLLo world"
@@ -1102,7 +1102,7 @@ test_expect_success LIBPCRE 'grep -P -w pattern' ' test_cmp expected actual ' -test_expect_success LIBPCRE 'grep -P backreferences work (the PCRE NO_AUTO_CAPTURE flag is not set)' ' +test_expect_success PCRE 'grep -P backreferences work (the PCRE NO_AUTO_CAPTURE flag is not set)' ' git grep -P -h "(?P<one>.)(?P=one)" hello_world >actual && test_cmp hello_world actual && git grep -P -h "(.)\1" hello_world >actual &&
@@ -1125,11 +1125,11 @@ test_expect_success 'grep invalidpattern properly dies with grep.patternType=ext test_must_fail git -c grep.patterntype=extended grep "a[" ' -test_expect_success LIBPCRE 'grep -P invalidpattern properly dies ' ' +test_expect_success PCRE '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_expect_success PCRE 'grep invalidpattern properly dies with grep.patternType=perl' ' test_must_fail git -c grep.patterntype=perl grep "a[" '
@@ -1198,13 +1198,13 @@ test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =perl, =e test_cmp expected actual ' -test_expect_success LIBPCRE 'grep -G -F -E -P pattern' ' +test_expect_success PCRE 'grep -G -F -E -P pattern' ' echo "d0:0" >expected && git grep -G -F -E -P "[\d]" d0 >actual && test_cmp expected actual ' -test_expect_success LIBPCRE 'grep pattern with grep.patternType=fixed, =basic, =extended, =perl' ' +test_expect_success PCRE 'grep pattern with grep.patternType=fixed, =basic, =extended, =perl' ' echo "d0:0" >expected && git \ -c grep.patterntype=fixed \
@@ -1215,7 +1215,7 @@ test_expect_success LIBPCRE 'grep pattern with grep.patternType=fixed, =basic, = test_cmp expected actual ' -test_expect_success LIBPCRE 'grep -P pattern with grep.patternType=fixed' ' +test_expect_success PCRE 'grep -P pattern with grep.patternType=fixed' ' echo "ab:a+b*c" >expected && git \ -c grep.patterntype=fixed \
@@ -1350,12 +1350,12 @@ space: line with leading space2 space: line with leading space3 EOF -test_expect_success LIBPCRE 'grep -E "^ "' ' +test_expect_success PCRE 'grep -E "^ "' ' git grep -E "^ " space >actual && test_cmp expected actual ' -test_expect_success LIBPCRE 'grep -P "^ "' ' +test_expect_success PCRE 'grep -P "^ "' ' git grep -P "^ " space >actual && test_cmp expected actual '
@@ -1512,7 +1512,7 @@ test_expect_success 'grep does not report i-t-a and assume unchanged with -L' ' test_cmp expected actual ' -test_expect_success LIBPCRE "grep with grep.patternType synonyms perl/pcre/pcre1" ' +test_expect_success PCRE "grep with grep.patternType synonyms perl/pcre/pcre1" ' echo "#include <stdio.h>" >expected && git -c grep.patternType=perl grep -h --no-line-number "st(?=dio)" >actual && test_cmp expected actual &&
t/t7812-grep-icase-non-ascii.sh +2 -2
@@ -20,13 +20,13 @@ test_expect_success REGEX_LOCALE 'grep literal string, no -F' ' git grep -i "TILRAUN: HALLÓ HEIMUR!" ' -test_expect_success GETTEXT_LOCALE,LIBPCRE 'grep pcre utf-8 icase' ' +test_expect_success GETTEXT_LOCALE,PCRE 'grep pcre utf-8 icase' ' git grep --perl-regexp "TILRAUN: H.lló Heimur!" && git grep --perl-regexp -i "TILRAUN: H.lló Heimur!" && git grep --perl-regexp -i "TILRAUN: H.LLÓ HEIMUR!" ' -test_expect_success GETTEXT_LOCALE,LIBPCRE 'grep pcre utf-8 string with "+"' ' +test_expect_success GETTEXT_LOCALE,PCRE 'grep pcre utf-8 string with "+"' ' test_write_lines "TILRAUN: Hallóó Heimur!" >file2 && git add file2 && git grep -l --perl-regexp "TILRAUN: H.lló+ Heimur!" >actual &&
t/t7813-grep-icase-iso.sh +1 -1
@@ -11,7 +11,7 @@ test_expect_success GETTEXT_ISO_LOCALE 'setup' ' export LC_ALL ' -test_expect_success GETTEXT_ISO_LOCALE,LIBPCRE 'grep pcre string' ' +test_expect_success GETTEXT_ISO_LOCALE,PCRE 'grep pcre string' ' git grep --perl-regexp -i "TILRAUN: H.ll� Heimur!" && git grep --perl-regexp -i "TILRAUN: H.LL� HEIMUR!" '
t/test-lib.sh +1 -1
@@ -1010,7 +1010,7 @@ esac ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_PERL" && test_set_prereq PERL test -z "$NO_PYTHON" && test_set_prereq PYTHON -test -n "$USE_LIBPCRE" && test_set_prereq LIBPCRE +test -n "$USE_LIBPCRE" && test_set_prereq PCRE test -z "$NO_GETTEXT" && test_set_prereq GETTEXT # Can we rely on git's output in the C locale?
Signature · 1 line
2.11.0
PATCH v3 12/18 grep: change the internal PCRE macro names to be PCRE1
In reply to Ævar Arnfjörð BjarmasonChange the internal USE_LIBPCRE define, & build options flag to use a naming convention ending in PCRE1, without changing the long-standing USE_LIBPCRE Makefile flag which enables this code.
This is for preparation for libpcre2 support where having things like USE_LIBPCRE and USE_LIBPCRE2 in any more places than we absolutely need to for backwards compatibility with old Makefile arguments would be confusing.
In some ways it would be better to change everything that now uses USE_LIBPCRE to use USE_LIBPCRE1, and to make specifying USE_LIBPCRE (or --with-pcre) an error. This would impose a one-time burden on packagers of git to s/USE_LIBPCRE/USE_LIBPCRE1/ in their build scripts.
However I'd like to leave the door open to making USE_LIBPCRE=YesPlease eventually mean USE_LIBPCRE2=YesPlease, i.e. once PCRE v2 is ubiquitous enough that it makes sense to make it the default.
This code and the USE_LIBPCRE Makefile argument was added in commit 63e7e9d8b6 ("git-grep: Learn PCRE", 2011-05-09). At the time there was no indication that the PCRE project would release an entirely new & incompatible API around 3 years later.
--- Makefile | 4 ++-- grep.c | 6 +++--- grep.h | 2 +- t/test-lib.sh | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-)
Makefile +2 -2
@@ -1086,7 +1086,7 @@ ifdef NO_LIBGEN_H endif ifdef USE_LIBPCRE - BASIC_CFLAGS += -DUSE_LIBPCRE + BASIC_CFLAGS += -DUSE_LIBPCRE1 ifdef LIBPCREDIR BASIC_CFLAGS += -I$(LIBPCREDIR)/include EXTLIBS += -L$(LIBPCREDIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCREDIR)/$(lib)
@@ -2238,7 +2238,7 @@ GIT-BUILD-OPTIONS: FORCE @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@+ @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@+ @echo NO_EXPAT=\''$(subst ','\'',$(subst ','\'',$(NO_EXPAT)))'\' >>$@+ - @echo USE_LIBPCRE=\''$(subst ','\'',$(subst ','\'',$(USE_LIBPCRE)))'\' >>$@+ + @echo USE_LIBPCRE1=\''$(subst ','\'',$(subst ','\'',$(USE_LIBPCRE)))'\' >>$@+ @echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@+ @echo NO_PYTHON=\''$(subst ','\'',$(subst ','\'',$(NO_PYTHON)))'\' >>$@+ @echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@+
grep.c +3 -3
@@ -325,7 +325,7 @@ static NORETURN void compile_regexp_failed(const struct grep_pat *p,die ("%s'%s': %s" , where, p->pattern, error); } -#ifdef USE_LIBPCRE +#ifdef USE_LIBPCRE1 static void compile_pcre_regexp (struct grep_pat *p,const struct grep_opt *opt) {const char *error;
@@ -377,7 +377,7 @@ static void free_pcre_regexp(struct grep_pat *p)pcre_free (p->pcre_extra_info); pcre_free((void *)p->pcre_tables); } -#else /* !USE_LIBPCRE */ +#else /* !USE_LIBPCRE1 */ static void compile_pcre_regexp (struct grep_pat *p,const struct grep_opt *opt) {die ("cannot use Perl-compatible regexes when not compiled with USE_LIBPCRE" );
@@ -392,7 +392,7 @@ static int pcrematch(struct grep_pat *p, const char *line, const char *eol,static void free_pcre_regexp (struct grep_pat *p) { } -#endif /* !USE_LIBPCRE */ +#endif /* !USE_LIBPCRE1 */ static int is_fixed (const char *s,size_t len) {
grep.h +1 -1
@@ -1,7 +1,7 @@#ifndef GREP_H #define GREP_H #include "color.h" -#ifdef USE_LIBPCRE +#ifdef USE_LIBPCRE1 #include <pcre.h> #else typedef int pcre ;
t/test-lib.sh +1 -1
@@ -1010,7 +1010,7 @@ esac ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_PERL" && test_set_prereq PERL test -z "$NO_PYTHON" && test_set_prereq PYTHON -test -n "$USE_LIBPCRE" && test_set_prereq PCRE +test -n "$USE_LIBPCRE1" && test_set_prereq PCRE test -z "$NO_GETTEXT" && test_set_prereq GETTEXT # Can we rely on git's output in the C locale?
Signature · 1 line
2.11.0
PATCH v3 13/18 grep: change the internal PCRE code & header names to be PCRE1
In reply to Ævar Arnfjörð BjarmasonChange the internal PCRE variable & function names to have a "1" suffix. This is for preparation for libpcre2 support, where having non-versioned names would be confusing.
The earlier "grep: change the internal PCRE macro names to be PCRE1" change elaborates on the motivations behind this commit.
--- builtin/grep.c | 4 ++-- grep.c | 56 ++++++++++++++++++++++++++++---------------------------- grep.h | 10 +++++----- revision.c | 2 +- 4 files changed, 36 insertions(+), 36 deletions(-)
builtin/grep.c +2 -2
@@ -490,7 +490,7 @@ static void compile_submodule_options(const struct grep_opt *opt,case GREP_PATTERN_TYPE_FIXED :argv_array_push (&submodule_options,"-F" );break ; -case GREP_PATTERN_TYPE_PCRE : +case GREP_PATTERN_TYPE_PCRE1 :argv_array_push (&submodule_options,"-P" );break ;case GREP_PATTERN_TYPE_UNSPECIFIED :
@@ -1022,7 +1022,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) GREP_PATTERN_TYPE_FIXED),OPT_SET_INT ('P' ,"perl-regexp" , &pattern_type_arg,N_ ("use Perl-compatible regular expressions" ), -GREP_PATTERN_TYPE_PCRE ), +GREP_PATTERN_TYPE_PCRE1 ),OPT_GROUP ("" ),OPT_BOOL ('n' ,"line-number" , &opt.linenum,N_ ("show line numbers" )), OPT_NEGBIT('h', NULL, &opt.pathname, N_("don't show filenames"), 1),
grep.c +28 -28
146 lines not on this page · raw message
grep.h +5 -5
@@ -46,9 +46,9 @@ struct grep_pat {size_t patternlen;enum grep_header_field field;regex_t regexp; -pcre *pcre_regexp; -pcre_extra *pcre_extra_info; -const unsigned char *pcre_tables; +pcre *pcre1_regexp; +pcre_extra *pcre1_extra_info; +const unsigned char *pcre1_tables;kwset_t kws; unsigned fixed:1; unsigned ignore_case:1;
@@ -68,7 +68,7 @@ enum grep_pattern_type {GREP_PATTERN_TYPE_BRE ,GREP_PATTERN_TYPE_ERE ,GREP_PATTERN_TYPE_FIXED , -GREP_PATTERN_TYPE_PCRE +GREP_PATTERN_TYPE_PCRE1 }; struct grep_expr {
@@ -111,7 +111,7 @@ struct grep_opt {int allow_textconv;int extended;int use_reflog_filter; -int pcre; +int pcre1;int relative;int pathname;int null_following_name;
revision.c +1 -1
@@ -1996,7 +1996,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg }else if (!strcmp (arg,"--fixed-strings" ) || !strcmp (arg,"-F" )) { revs->grep_filter.pattern_type_option =GREP_PATTERN_TYPE_FIXED ; }else if (!strcmp (arg,"--perl-regexp" ) || !strcmp (arg,"-P" )) { - revs->grep_filter.pattern_type_option =GREP_PATTERN_TYPE_PCRE ; + revs->grep_filter.pattern_type_option =GREP_PATTERN_TYPE_PCRE1 ; }else if (!strcmp (arg,"--all-match" )) { revs->grep_filter.all_match =1 ; }else if (!strcmp (arg,"--invert-grep" )) {
Signature · 1 line
2.11.0
PATCH v3 14/18 perf: add a performance comparison test of grep -E and -P
In reply to Ævar Arnfjörð BjarmasonAdd a very basic performance comparison test comparing the POSIX extended & pcre1 engines.
I'm skipping the "basic" POSIX engine because supporting its alternate regex syntax is hard, although it would be interesting to test it, at least under glibc it seems to be an entirely different engine, since it can have very different performance even for patterns that mean the same thing under extended and non-extended POSIX regular expression syntax.
Running this on an i7 3.4GHz Linux 3.16.0-4 Debian testing against a checkout of linux.git & latest upstream PCRE, both PCRE and git compiled with -O3:
$ GIT_PERF_LARGE_REPO=~/g/linux ./run p7820-grep-engines.sh
[...]
Test this tree
-----------------------------------------------------------------------------
7820.1: extended with how.to 0.28(1.23+0.44)
7820.2: extended with ^how to 0.26(1.15+0.38)
7820.3: extended with \w+our\w* 6.06(38.44+0.35)
7820.4: extended with -?-?-?-?-?-?-?-?-?-?-?-----------$ 0.37(1.57+0.38)
7820.5: pcre1 with how.to 0.26(1.15+0.37)
7820.6: pcre1 with ^how to 0.46(2.66+0.31)
7820.7: pcre1 with \w+our\w* 16.42(99.42+0.48)
7820.8: pcre1 with -?-?-?-?-?-?-?-?-?-?-?-----------$ 81.52(275.37+0.41)--- t/perf/p7820-grep-engines.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 t/perf/p7820-grep-engines.sh
t/perf/p7820-grep-engines.sh new file +25 -0
@@ -0,0 +1,25 @@ +#!/bin/sh + +test_description="Comparison of git-grep's regex engines" + +. ./perf-lib.sh + +test_perf_large_repo +test_checkout_worktree + +for engine in extended pcre1 +do + # Patterns stolen from http://sljit.sourceforge.net/pcre.html + for pattern in \ + 'how.to' \ + '^how to' \ + '\w+our\w*' \ + '-?-?-?-?-?-?-?-?-?-?-?-----------$' + do + test_perf "$engine with $pattern" " + git -c grep.patternType=$engine grep -- '$pattern' || : + " + done +done + +test_done
Signature · 1 line
2.11.0
PATCH v3 15/18 grep: add support for the PCRE v1 JIT API
In reply to Ævar Arnfjörð BjarmasonChange the grep PCRE v1 code to use JIT when available. When PCRE support was initially added in commit 63e7e9d8b6 ("git-grep: Learn PCRE", 2011-05-09) PCRE had no JIT support, it was integrated into 8.20 released on 2011-10-21.
When JIT support is enabled the PCRE performance usually improves by more than 50%. The pattern compilation times are relatively slower, but those relative numbers are tiny, and are easily made back in all but the most trivial cases of grep. Detailed benchhmarks are available
at: http://sljit.sourceforge.net/pcre.html
With this change the difference in a t/perf/p7820-grep-engines.sh run is, shown with git --word-diff:
7820.1: extended with how.to [-0.28(1.23+0.44)-]{+0.28(1.18+0.39)+}
7820.2: extended with ^how to [-0.26(1.15+0.38)-]{+0.27(1.13+0.40)+}
7820.3: extended with \w+our\w* [-6.06(38.44+0.35)-]{+6.11(38.66+0.32)+}
7820.4: extended with -?-?-?-?-?-?-?-?-?-?-?-----------$ [-0.37(1.57+0.38)-]{+0.37(1.56+0.42)+}
7820.5: pcre1 with how.to [-0.26(1.15+0.37)-]{+0.19(0.39+0.55)+}
7820.6: pcre1 with ^how to [-0.46(2.66+0.31)-]{+0.22(0.67+0.44)+}
7820.7: pcre1 with \w+our\w* [-16.42(99.42+0.48)-]{+0.51(3.05+0.24)+}
7820.8: pcre1 with -?-?-?-?-?-?-?-?-?-?-?-----------$ [-81.52(275.37+0.41)-]{+5.16(19.31+0.33)+}The conditional support for JIT is implemented as suggested in the pcrejit(3) man page. E.g. defining PCRE_STUDY_JIT_COMPILE to 0 if it's not present.
There's no graceful fallback if pcre_jit_stack_alloc() fails under PCRE_CONFIG_JIT, instead the program will abort. I don't think this is worth handling, it'll only fail in cases where malloc() doesn't work, in which case we're screwed anyway.
--- grep.c | 27 ++++++++++++++++++++++++++- grep.h | 5 +++++ 2 files changed, 31 insertions(+), 1 deletion(-)
grep.c +26 -1
@@ -331,6 +331,9 @@ static void compile_pcre1_regexp(struct grep_pat *p, const struct grep_opt *opt)const char *error;int erroffset;int options =PCRE_MULTILINE ; +#ifdef PCRE_CONFIG_JIT +int canjit; +#endif if (opt->ignore_case) {if (has_non_ascii (p->pattern))
@@ -345,9 +348,19 @@ static void compile_pcre1_regexp(struct grep_pat *p, const struct grep_opt *opt)if (!p->pcre1_regexp)compile_regexp_failed (p, error); - p->pcre1_extra_info =pcre_study (p->pcre1_regexp,0 , &error); + p->pcre1_extra_info =pcre_study (p->pcre1_regexp,PCRE_STUDY_JIT_COMPILE , &error);if (!p->pcre1_extra_info && error)die ("%s" , error); + +#ifdef PCRE_CONFIG_JIT +pcre_config (PCRE_CONFIG_JIT , &canjit); +if (canjit ==1 ) { + p->pcre1_jit_stack =pcre_jit_stack_alloc (1 ,1024 *1024 ); +if (!p->pcre1_jit_stack) +die ("BUG: Couldn't allocate PCRE JIT stack" ); +pcre_assign_jit_stack (p->pcre1_extra_info,NULL , p->pcre1_jit_stack); + } +#endif } static int pcre1match(struct grep_pat *p, const char *line, const char *eol,
@@ -358,8 +371,15 @@ static int pcre1match(struct grep_pat *p, const char *line, const char *eol,if (eflags ®_NOTBOL ) flags |=PCRE_NOTBOL ; +#ifdef PCRE_CONFIG_JIT + ret =pcre_jit_exec (p->pcre1_regexp, p->pcre1_extra_info, line, eol - line, +0 , flags, ovector,ARRAY_SIZE (ovector), + p->pcre1_jit_stack); +#else ret =pcre_exec (p->pcre1_regexp, p->pcre1_extra_info, line, eol - line,0 , flags, ovector,ARRAY_SIZE (ovector)); +#endif +if (ret <0 && ret !=PCRE_ERROR_NOMATCH )die ("pcre_exec failed with error code %d" , ret);if (ret >0 ) {
@@ -374,7 +394,12 @@ static int pcre1match(struct grep_pat *p, const char *line, const char *eol,static void free_pcre1_regexp (struct grep_pat *p) {pcre_free (p->pcre1_regexp); +#ifdef PCRE_CONFIG_JIT +pcre_free_study (p->pcre1_extra_info); +pcre_jit_stack_free (p->pcre1_jit_stack); +#else pcre_free (p->pcre1_extra_info); +#endif pcre_free ((void *)p->pcre1_tables); }#else /* !USE_LIBPCRE1 */
grep.h +5 -0
@@ -3,9 +3,13 @@#include "color.h" #ifdef USE_LIBPCRE1 #include <pcre.h> +#ifndef PCRE_STUDY_JIT_COMPILE +#define PCRE_STUDY_JIT_COMPILE 0 +#endif #else typedef int pcre ;typedef int pcre_extra ; +typedef int pcre_jit_stack ;#endif #include "kwset.h" #include "thread-utils.h"
@@ -48,6 +52,7 @@ struct grep_pat {regex_t regexp;pcre *pcre1_regexp;pcre_extra *pcre1_extra_info; +pcre_jit_stack *pcre1_jit_stack;const unsigned char *pcre1_tables;kwset_t kws; unsigned fixed:1;
Signature · 1 line
2.11.0
PATCH v3 16/18 grep: add support for PCRE v2
In reply to Ævar Arnfjörð BjarmasonAdd support for v2 of the PCRE API. This is a new major version of PCRE that came out in early 2015[1].
The regular expression syntax is the same, but while the API is similar-ish, pretty much every function is either renamed or takes different arguments. Thus using it via entirely new functions makes sense, as opposed to trying to e.g. have one compile_pcre_pattern() that would call either PCRE v1 or v2 functions.
Git can now be compiled with any combination of USE_LIBPCRE=[YesPlease|] & USE_LIBPCRE2=[YesPlease|]. If both are provided the version of the PCRE library can be selected at runtime with grep.PatternType, but the default (for now) is v1.
This table shows what the various combinations do, depending on what libraries Git is compiled against:
|------------------+-----+-----+----------|
| grep.PatternType | v1 | v2 | v1 && v2 |
|------------------+-----+-----+----------|
| perl | v1 | v2 | v1 |
| pcre | v1 | v2 | v1 |
| pcre1 | v1 | ERR | v1 |
| pcre2 | ERR | v2 | v2 |
|------------------+-----+-----+----------|When Git is only compiled with v2 grep.PatternType=perl, --perl-regexp & -P will use v2. All tests pass with this new PCRE version. When Git is compiled with both v1 & v2 most of the tests will only test v1, but there are some v2-specific tests that will be run.
With earlier patches to enable JIT for PCRE v1 the performance of the release versions of both libraries have almost exactly the same performance, with PCRE v2 being around 1% slower.
However after I reported this to the pcre-dev mailing list[2] I got a lot of help with the API use from Zoltán Herczeg, he subsequently optimized some of the JIT functionality in v2 of the library.
Running the p7820-grep-engines.sh performance test against the latest Subversion trunk of both, with both them and git compiled as -O3, and the test run against linux.git, gives the following results:
7820.1: extended with how.to 0.27(1.22+0.34)
7820.2: extended with ^how to 0.27(1.18+0.36)
7820.3: extended with \w+our\w* 6.09(38.64+0.32)
7820.4: extended with -?-?-?-?-?-?-?-?-?-?-?-----------$ 0.38(1.69+0.28)
7820.5: pcre1 with how.to 0.19(0.42+0.53)
7820.6: pcre1 with ^how to 0.23(0.58+0.50)
7820.7: pcre1 with \w+our\w* 0.50(2.93+0.34)
7820.8: pcre1 with -?-?-?-?-?-?-?-?-?-?-?-----------$ 5.12(19.32+0.38)
7820.9: pcre2 with how.to 0.19(0.34+0.57)
7820.10: pcre2 with ^how to 0.19(0.29+0.60)
7820.11: pcre2 with \w+our\w* 0.51(2.85+0.41)
7820.12: pcre2 with -?-?-?-?-?-?-?-?-?-?-?-----------$ 5.04(19.27+0.31)I.e. the two are neck-to-neck, but PCRE v2 usually pulls ahead, when it does it's up to 20% faster.
A brief note on thread safety: As noted in pcre2api(3) & pcre2jit(3) the compiled pattern can be shared between threads, but not some of the JIT context, however the grep threading support does all pattern & JIT compilation in separate threads, so this code doesn't need to concern itself with thread safety.
See commit 63e7e9d8b6 ("git-grep: Learn PCRE", 2011-05-09) for the initial addition of PCRE v1. This change follows some of the same patterns it did (and which were discussed on list at the time), e.g. mocking up types with typedef instead of ifdef-ing them out when USE_LIBPCRE2 isn't defined. This adds some trivial memory use to the program, but makes the code look nicer.
1. https://lists.exim.org/lurker/message/20150105.162835.0666407a.en.html
2. https://lists.exim.org/lurker/thread/20170419.172322.833ee099.en.html
--- Documentation/config.txt | 14 ++-- Makefile | 18 +++++ builtin/grep.c | 7 +- configure.ac | 49 +++++++++++- grep.c | 149 ++++++++++++++++++++++++++++++++++++- grep.h | 21 +++++- revision.c | 2 +- t/README | 12 +++ t/perf/p7820-grep-engines.sh | 2 +- t/t7810-grep.sh | 30 +++++++- t/t7813-grep-icase-iso.sh | 11 ++- t/t7814-grep-recurse-submodules.sh | 12 ++- t/test-lib.sh | 4 +- 13 files changed, 304 insertions(+), 27 deletions(-)
Documentation/config.txt +6 -8
@@ -1625,14 +1625,12 @@ grep.patternType:: `--fixed-strings`, or `--perl-regexp` option accordingly, while the value 'default' will return to the default matching behavior. + -The 'pcre' and 'pcre1' values are synonyms for 'perl'. The other -values starting with 'pcre' are reserved for future use, e.g. if we'd -like to use 'pcre2' for the PCRE v2 library. -+ -In the future 'perl' and 'pcre' might become synonyms for some other -implementation or PCRE version, such as 'pcre2', while the more -specific 'pcre1' & 'pcre2' might throw errors depending on whether git -is compiled to include those libraries. +The 'perl' and 'pcre' values are synonyms. Depending on which PCRE +library Git was compiled with either or both of 'pcre1' and 'pcre2' +might also be available. ++ +If both are available Git currently defaults to 'pcre1', but this +might change in future versions. grep.extendedRegexp:: If set to true, enable `--extended-regexp` option by default. This
Makefile +18 -0
@@ -32,6 +32,14 @@ all:: # Define LIBPCREDIR=/foo/bar if your libpcre header and library files are in # /foo/bar/include and /foo/bar/lib directories. # +# Define USE_LIBPCRE2 if you have and want to use libpcre2. Various +# commands such as log and grep offer runtime options to use +# Perl-compatible regular expressions instead of standard or extended +# POSIX regular expressions. +# +# Define LIBPCRE2DIR=/foo/bar if your libpcre2 header and library +# files are in /foo/bar/include and /foo/bar/lib directories. +# # Define HAVE_ALLOCA_H if you have working alloca(3) defined in that header. # # Define NO_CURL if you do not have libcurl installed. git-http-fetch and
@@ -1094,6 +1102,15 @@ ifdef USE_LIBPCRE EXTLIBS += -lpcre endif +ifdef USE_LIBPCRE2 + BASIC_CFLAGS += -DUSE_LIBPCRE2 + ifdef LIBPCRE2DIR + BASIC_CFLAGS += -I$(LIBPCRE2DIR)/include + EXTLIBS += -L$(LIBPCRE2DIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCR2EDIR)/$(lib) + endif + EXTLIBS += -lpcre2-8 +endif + ifdef HAVE_ALLOCA_H BASIC_CFLAGS += -DHAVE_ALLOCA_H endif
@@ -2239,6 +2256,7 @@ GIT-BUILD-OPTIONS: FORCE @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@+ @echo NO_EXPAT=\''$(subst ','\'',$(subst ','\'',$(NO_EXPAT)))'\' >>$@+ @echo USE_LIBPCRE1=\''$(subst ','\'',$(subst ','\'',$(USE_LIBPCRE)))'\' >>$@+ + @echo USE_LIBPCRE2=\''$(subst ','\'',$(subst ','\'',$(USE_LIBPCRE2)))'\' >>$@+ @echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@+ @echo NO_PYTHON=\''$(subst ','\'',$(subst ','\'',$(NO_PYTHON)))'\' >>$@+ @echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@+
builtin/grep.c +5 -2
@@ -490,11 +490,14 @@ static void compile_submodule_options(const struct grep_opt *opt,case GREP_PATTERN_TYPE_FIXED :argv_array_push (&submodule_options,"-F" );break ; -case GREP_PATTERN_TYPE_PCRE1 : +case GREP_PATTERN_TYPE_PCRE :argv_array_push (&submodule_options,"-P" );break ;case GREP_PATTERN_TYPE_UNSPECIFIED :break ; +case GREP_PATTERN_TYPE_PCRE1 : +case GREP_PATTERN_TYPE_PCRE2 : +die ("BUG: Command-line option for pcre1 or pcre2 added without updating switch statement" );default :die ("BUG: Added a new grep pattern type without updating switch statement" ); }
@@ -1022,7 +1025,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) GREP_PATTERN_TYPE_FIXED),OPT_SET_INT ('P' ,"perl-regexp" , &pattern_type_arg,N_ ("use Perl-compatible regular expressions" ), -GREP_PATTERN_TYPE_PCRE1 ), +GREP_PATTERN_TYPE_PCRE ),OPT_GROUP ("" ),OPT_BOOL ('n' ,"line-number" , &opt.linenum,N_ ("show line numbers" )), OPT_NEGBIT('h', NULL, &opt.pathname, N_("don't show filenames"), 1),
configure.ac +47 -2
67 lines not on this page · raw message
grep.c +147 -2
204 lines not on this page · raw message
grep.h +20 -1
@@ -11,6 +11,16 @@ typedef int pcre;typedef int pcre_extra ;typedef int pcre_jit_stack ;#endif +#ifdef USE_LIBPCRE2 +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> +#else +typedef int pcre2_code ; +typedef int pcre2_match_data ; +typedef int pcre2_compile_context ; +typedef int pcre2_match_context ; +typedef int pcre2_jit_stack ; +#endif #include "kwset.h" #include "thread-utils.h" #include "userdiff.h"
@@ -54,6 +64,12 @@ struct grep_pat {pcre_extra *pcre1_extra_info;pcre_jit_stack *pcre1_jit_stack;const unsigned char *pcre1_tables; +pcre2_code *pcre2_pattern; +pcre2_match_data *pcre2_match_data; +pcre2_compile_context *pcre2_ccontext; +pcre2_match_context *pcre2_match_context; +pcre2_jit_stack *pcre2_jit_stack; +int pcre2_jit_on;kwset_t kws; unsigned fixed:1; unsigned ignore_case:1;
@@ -73,7 +89,9 @@ enum grep_pattern_type {GREP_PATTERN_TYPE_BRE ,GREP_PATTERN_TYPE_ERE ,GREP_PATTERN_TYPE_FIXED , -GREP_PATTERN_TYPE_PCRE1 +GREP_PATTERN_TYPE_PCRE , +GREP_PATTERN_TYPE_PCRE1 , +GREP_PATTERN_TYPE_PCRE2 }; struct grep_expr {
@@ -117,6 +135,7 @@ struct grep_opt {int extended;int use_reflog_filter;int pcre1; +int pcre2;int relative;int pathname;int null_following_name;
revision.c +1 -1
@@ -1996,7 +1996,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg }else if (!strcmp (arg,"--fixed-strings" ) || !strcmp (arg,"-F" )) { revs->grep_filter.pattern_type_option =GREP_PATTERN_TYPE_FIXED ; }else if (!strcmp (arg,"--perl-regexp" ) || !strcmp (arg,"-P" )) { - revs->grep_filter.pattern_type_option =GREP_PATTERN_TYPE_PCRE1 ; + revs->grep_filter.pattern_type_option =GREP_PATTERN_TYPE_PCRE ; }else if (!strcmp (arg,"--all-match" )) { revs->grep_filter.all_match =1 ; }else if (!strcmp (arg,"--invert-grep" )) {
t/README +12 -0
@@ -808,6 +808,18 @@ use these, and "test_set_prereq" for how to define your own. Git was compiled with support for PCRE. Wrap any tests that use git-grep --perl-regexp or git-grep -P in these. + - LIBPCRE1 + + Git was compiled with PCRE v1 support via + USE_LIBPCRE=YesPlease. Wrap any PCRE using tests that for some + reason need v1 of the PCRE library instead of v2 in these. + + - LIBPCRE2 + + Git was compiled with PCRE v2 support via + USE_LIBPCRE2=YesPlease. Wrap any PCRE using tests that for some + reason need v2 of the PCRE library instead of v1 in these. + - CASE_INSENSITIVE_FS Test is run on a case insensitive file system.
t/perf/p7820-grep-engines.sh +1 -1
@@ -7,7 +7,7 @@ test_description="Comparison of git-grep's regex engines" test_perf_large_repo test_checkout_worktree -for engine in extended pcre1 +for engine in extended pcre1 pcre2 do # Patterns stolen from http://sljit.sourceforge.net/pcre.html for pattern in \
t/t7810-grep.sh +27 -3
@@ -1063,6 +1063,16 @@ test_expect_success PCRE 'grep -P pattern' ' test_cmp expected actual ' +test_expect_success LIBPCRE1 'grep libpcre1 pattern' ' + git -c grep.patternType=pcre1 grep "\p{Ps}.*?\p{Pe}" hello.c >actual && + test_cmp expected actual +' + +test_expect_success LIBPCRE2 'grep libpcre2 pattern' ' + git -c grep.patternType=pcre2 grep "\p{Ps}.*?\p{Pe}" hello.c >actual && + test_cmp expected actual +' + test_expect_success 'grep pattern with grep.extendedRegexp=true' ' >empty && test_must_fail git -c grep.extendedregexp=true \
@@ -1512,14 +1522,28 @@ test_expect_success 'grep does not report i-t-a and assume unchanged with -L' ' test_cmp expected actual ' -test_expect_success PCRE "grep with grep.patternType synonyms perl/pcre/pcre1" ' +test_expect_success PCRE "grep with grep.patternType synonyms perl/pcre" ' echo "#include <stdio.h>" >expected && git -c grep.patternType=perl grep -h --no-line-number "st(?=dio)" >actual && test_cmp expected actual && git -c grep.patternType=pcre grep -h --no-line-number "st(?=dio)" >actual && - test_cmp expected actual && - git -c grep.patternType=pcre1 grep -h --no-line-number "st(?=dio)" >actual && test_cmp expected actual ' +test_expect_success LIBPCRE1 "grep with grep.patternType=pcre1" ' + echo "#include <stdio.h>" >expected && + git -c grep.patternType=pcre1 grep -h --no-line-number "st(?=dio)" >actual && + test_cmp expected actual && + test_must_fail git -c grep.patternType=pcre1 grep "foo(?+bar)" 2>error && + test_i18ngrep -q "digit expected after" error +' + +test_expect_success LIBPCRE2 "grep with grep.patternType=pcre2" ' + echo "#include <stdio.h>" >expected && + git -c grep.patternType=pcre2 grep -h --no-line-number "st(?=dio)" >actual && + test_cmp expected actual && + test_must_fail git -c grep.patternType=pcre2 grep "foo(?+bar)" 2>error && + test_i18ngrep -q "digit expected after" error +' + test_done
t/t7813-grep-icase-iso.sh +7 -4
@@ -11,9 +11,12 @@ test_expect_success GETTEXT_ISO_LOCALE 'setup' ' export LC_ALL ' -test_expect_success GETTEXT_ISO_LOCALE,PCRE 'grep pcre string' ' - git grep --perl-regexp -i "TILRAUN: H.ll� Heimur!" && - git grep --perl-regexp -i "TILRAUN: H.LL� HEIMUR!" -' +for pcrev in 1 2 +do + test_expect_success GETTEXT_ISO_LOCALE,LIBPCRE$pcrev "grep -i with i18n string using libpcre$pcrev" " + git -c grep.patternType=pcre$pcrev grep -i \"TILRAUN: H.ll� Heimur!\" && + git -c grep.patternType=pcre$pcrev grep -i \"TILRAUN: H.LL� HEIMUR!\" + " +done test_done
t/t7814-grep-recurse-submodules.sh +10 -2
@@ -361,8 +361,16 @@ test_expect_success 'grep --recurse-submodules should pass the pattern type alon test_cmp expect actual && git -c grep.patternType=pcre grep --recurse-submodules -e "(.|.)[\d]" >actual && test_cmp expect actual && - git -c grep.patternType=pcre1 grep --recurse-submodules -e "(.|.)[\d]" >actual && - test_cmp expect actual + if test_have_prereq LIBPCRE1 + then + git -c grep.patternType=pcre1 grep --recurse-submodules -e "(.|.)[\d]" >actual && + test_cmp expect actual + fi && + if test_have_prereq LIBPCRE2 + then + git -c grep.patternType=pcre2 grep --recurse-submodules -e "(.|.)[\d]" >actual && + test_cmp expect actual + fi fi '
t/test-lib.sh +3 -1
@@ -1010,7 +1010,9 @@ esac ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_PERL" && test_set_prereq PERL test -z "$NO_PYTHON" && test_set_prereq PYTHON -test -n "$USE_LIBPCRE1" && test_set_prereq PCRE +test -n "$USE_LIBPCRE1$USE_LIBPCRE2" && test_set_prereq PCRE +test -n "$USE_LIBPCRE1" && test_set_prereq LIBPCRE1 +test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2 test -z "$NO_GETTEXT" && test_set_prereq GETTEXT # Can we rely on git's output in the C locale?
Signature · 1 line
2.11.0
PATCH v3 17/18 grep: remove support concurrent use of both PCRE v1 & v2
In reply to Ævar Arnfjörð BjarmasonRemove the support for concurrently using PCRE v1 & v2 by compiling Git with support for both.
Having access to both at runtime via grep.patternType=[pcre1|pcre2] makes it easier for the developer hacking on the PCRE implementations to test them concurrently, but adds confusion for everyone else, particularly Git users who have no reason to concurrently use both libraries.
Now either USE_LIBPCRE1=YesPlease (or its alias USE_LIBPCRE) or USE_LIBPCRE2=YesPlease can be supplied when building git, but providing both will yield an error, similarly providing both --with-libpcre1 & --with-libpcre2 to the configure script will produce an error.
--- Documentation/config.txt | 7 ---- Makefile | 36 +++++++++---------- builtin/grep.c | 3 -- configure.ac | 72 +++++++++++++++++++++----------------- grep.c | 19 +--------- grep.h | 4 +-- t/README | 12 ------- t/perf/p7820-grep-engines.sh | 2 +- t/t7810-grep.sh | 30 +--------------- t/t7814-grep-recurse-submodules.sh | 14 +------- t/test-lib.sh | 5 ++- 11 files changed, 65 insertions(+), 139 deletions(-)
Documentation/config.txt +0 -7
@@ -1624,13 +1624,6 @@ grep.patternType:: '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. -+ -The 'perl' and 'pcre' values are synonyms. Depending on which PCRE -library Git was compiled with either or both of 'pcre1' and 'pcre2' -might also be available. -+ -If both are available Git currently defaults to 'pcre1', but this -might change in future versions. grep.extendedRegexp:: If set to true, enable `--extended-regexp` option by default. This
Makefile +18 -18
@@ -29,16 +29,13 @@ all:: # Perl-compatible regular expressions instead of standard or extended # POSIX regular expressions. # -# Define LIBPCREDIR=/foo/bar if your libpcre header and library files are in -# /foo/bar/include and /foo/bar/lib directories. +# Currently USE_LIBPCRE is a synonym for USE_LIBPCRE1, define +# USE_LIBPCRE2 instead if you'd like to use version 2 of the PCRE +# library. The USE_LIBPCRE flag will likely be changed to mean v2 by +# default in future releases. # -# Define USE_LIBPCRE2 if you have and want to use libpcre2. Various -# commands such as log and grep offer runtime options to use -# Perl-compatible regular expressions instead of standard or extended -# POSIX regular expressions. -# -# Define LIBPCRE2DIR=/foo/bar if your libpcre2 header and library -# files are in /foo/bar/include and /foo/bar/lib directories. +# Define LIBPCREDIR=/foo/bar if your PCRE header and library files are in +# /foo/bar/include and /foo/bar/lib directories. # # Define HAVE_ALLOCA_H if you have working alloca(3) defined in that header. #
@@ -1093,24 +1090,27 @@ ifdef NO_LIBGEN_H COMPAT_OBJS += compat/basename.o endif -ifdef USE_LIBPCRE - BASIC_CFLAGS += -DUSE_LIBPCRE1 - ifdef LIBPCREDIR - BASIC_CFLAGS += -I$(LIBPCREDIR)/include - EXTLIBS += -L$(LIBPCREDIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCREDIR)/$(lib) +USE_LIBPCRE1 ?= $(USE_LIBPCRE) + +ifneq (,$(USE_LIBPCRE1)) + ifdef USE_LIBPCRE2 +$(error Only set USE_LIBPCRE1 (or its alias USE_LIBPCRE) or USE_LIBPCRE2, not both!) endif + + BASIC_CFLAGS += -DUSE_LIBPCRE1 EXTLIBS += -lpcre endif ifdef USE_LIBPCRE2 BASIC_CFLAGS += -DUSE_LIBPCRE2 - ifdef LIBPCRE2DIR - BASIC_CFLAGS += -I$(LIBPCRE2DIR)/include - EXTLIBS += -L$(LIBPCRE2DIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCR2EDIR)/$(lib) - endif EXTLIBS += -lpcre2-8 endif +ifdef LIBPCREDIR + BASIC_CFLAGS += -I$(LIBPCREDIR)/include + EXTLIBS += -L$(LIBPCREDIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCREDIR)/$(lib) +endif + ifdef HAVE_ALLOCA_H BASIC_CFLAGS += -DHAVE_ALLOCA_H endif
builtin/grep.c +0 -3
@@ -495,9 +495,6 @@ static void compile_submodule_options(const struct grep_opt *opt,break ;case GREP_PATTERN_TYPE_UNSPECIFIED :break ; -case GREP_PATTERN_TYPE_PCRE1 : -case GREP_PATTERN_TYPE_PCRE2 : -die ("BUG: Command-line option for pcre1 or pcre2 added without updating switch statement" );default :die ("BUG: Added a new grep pattern type without updating switch statement" ); }
configure.ac +40 -32
126 lines not on this page · raw message
grep.c +1 -18
@@ -60,13 +60,8 @@ static int parse_pattern_type_arg(const char *opt, const char *arg)return GREP_PATTERN_TYPE_ERE ; else if (!strcmp(arg, "fixed"))return GREP_PATTERN_TYPE_FIXED ; - else if (!strcmp(arg, "perl") || - !strcmp(arg, "pcre")) + else if (!strcmp(arg, "perl"))return GREP_PATTERN_TYPE_PCRE ; - else if (!strcmp(arg, "pcre1")) -return GREP_PATTERN_TYPE_PCRE1 ; - else if (!strcmp(arg, "pcre2")) -return GREP_PATTERN_TYPE_PCRE2 ;die ("bad %s argument: %s" , opt, arg); }
@@ -215,18 +210,6 @@ static void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, st opt->pcre2 =1 ;#endif break ; - -case GREP_PATTERN_TYPE_PCRE1 : - opt->fixed =0 ; - opt->pcre1 =1 ; - opt->pcre2 =0 ; -break ; - -case GREP_PATTERN_TYPE_PCRE2 : - opt->fixed =0 ; - opt->pcre1 =0 ; - opt->pcre2 =1 ; -break ; } }
grep.h +1 -3
@@ -89,9 +89,7 @@ enum grep_pattern_type {GREP_PATTERN_TYPE_BRE ,GREP_PATTERN_TYPE_ERE ,GREP_PATTERN_TYPE_FIXED , -GREP_PATTERN_TYPE_PCRE , -GREP_PATTERN_TYPE_PCRE1 , -GREP_PATTERN_TYPE_PCRE2 +GREP_PATTERN_TYPE_PCRE }; struct grep_expr {
t/README +0 -12
@@ -808,18 +808,6 @@ use these, and "test_set_prereq" for how to define your own. Git was compiled with support for PCRE. Wrap any tests that use git-grep --perl-regexp or git-grep -P in these. - - LIBPCRE1 - - Git was compiled with PCRE v1 support via - USE_LIBPCRE=YesPlease. Wrap any PCRE using tests that for some - reason need v1 of the PCRE library instead of v2 in these. - - - LIBPCRE2 - - Git was compiled with PCRE v2 support via - USE_LIBPCRE2=YesPlease. Wrap any PCRE using tests that for some - reason need v2 of the PCRE library instead of v1 in these. - - CASE_INSENSITIVE_FS Test is run on a case insensitive file system.
t/perf/p7820-grep-engines.sh +1 -1
@@ -7,7 +7,7 @@ test_description="Comparison of git-grep's regex engines" test_perf_large_repo test_checkout_worktree -for engine in extended pcre1 pcre2 +for engine in extended perl do # Patterns stolen from http://sljit.sourceforge.net/pcre.html for pattern in \
t/t7810-grep.sh +1 -29
@@ -1063,16 +1063,6 @@ test_expect_success PCRE 'grep -P pattern' ' test_cmp expected actual ' -test_expect_success LIBPCRE1 'grep libpcre1 pattern' ' - git -c grep.patternType=pcre1 grep "\p{Ps}.*?\p{Pe}" hello.c >actual && - test_cmp expected actual -' - -test_expect_success LIBPCRE2 'grep libpcre2 pattern' ' - git -c grep.patternType=pcre2 grep "\p{Ps}.*?\p{Pe}" hello.c >actual && - test_cmp expected actual -' - test_expect_success 'grep pattern with grep.extendedRegexp=true' ' >empty && test_must_fail git -c grep.extendedregexp=true \
@@ -1522,28 +1512,10 @@ test_expect_success 'grep does not report i-t-a and assume unchanged with -L' ' test_cmp expected actual ' -test_expect_success PCRE "grep with grep.patternType synonyms perl/pcre" ' +test_expect_success PCRE "grep with grep.patternType synonyms perl" ' echo "#include <stdio.h>" >expected && git -c grep.patternType=perl grep -h --no-line-number "st(?=dio)" >actual && - test_cmp expected actual && - git -c grep.patternType=pcre grep -h --no-line-number "st(?=dio)" >actual && test_cmp expected actual ' -test_expect_success LIBPCRE1 "grep with grep.patternType=pcre1" ' - echo "#include <stdio.h>" >expected && - git -c grep.patternType=pcre1 grep -h --no-line-number "st(?=dio)" >actual && - test_cmp expected actual && - test_must_fail git -c grep.patternType=pcre1 grep "foo(?+bar)" 2>error && - test_i18ngrep -q "digit expected after" error -' - -test_expect_success LIBPCRE2 "grep with grep.patternType=pcre2" ' - echo "#include <stdio.h>" >expected && - git -c grep.patternType=pcre2 grep -h --no-line-number "st(?=dio)" >actual && - test_cmp expected actual && - test_must_fail git -c grep.patternType=pcre2 grep "foo(?+bar)" 2>error && - test_i18ngrep -q "digit expected after" error -' - test_done
t/t7814-grep-recurse-submodules.sh +1 -13
@@ -358,19 +358,7 @@ test_expect_success 'grep --recurse-submodules should pass the pattern type alon EOF test_cmp expect actual && git -c grep.patternType=perl grep --recurse-submodules -e "(.|.)[\d]" >actual && - test_cmp expect actual && - git -c grep.patternType=pcre grep --recurse-submodules -e "(.|.)[\d]" >actual && - test_cmp expect actual && - if test_have_prereq LIBPCRE1 - then - git -c grep.patternType=pcre1 grep --recurse-submodules -e "(.|.)[\d]" >actual && - test_cmp expect actual - fi && - if test_have_prereq LIBPCRE2 - then - git -c grep.patternType=pcre2 grep --recurse-submodules -e "(.|.)[\d]" >actual && - test_cmp expect actual - fi + test_cmp expect actual fi '
t/test-lib.sh +2 -3
@@ -1010,9 +1010,8 @@ esac ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_PERL" && test_set_prereq PERL test -z "$NO_PYTHON" && test_set_prereq PYTHON -test -n "$USE_LIBPCRE1$USE_LIBPCRE2" && test_set_prereq PCRE -test -n "$USE_LIBPCRE1" && test_set_prereq LIBPCRE1 -test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2 +test -n "$USE_LIBPCRE1" && test_set_prereq PCRE +test -n "$USE_LIBPCRE2" && test_set_prereq PCRE test -z "$NO_GETTEXT" && test_set_prereq GETTEXT # Can we rely on git's output in the C locale?
Signature · 1 line
2.11.0
PATCH v3 18/18 Makefile & configure: make PCRE v2 the default PCRE implementation
In reply to Ævar Arnfjörð BjarmasonChange the USE_LIBPCRE=YesPlease & --with-libpcre flags to the Makefile & configure script, respectively, to mean use PCRE v2, not PCRE v1. The legacy library is still available on request via USE_LIBPCRE1=YesPlease or --with-libpcre1.
--- Makefile | 21 ++++++++++----------- configure.ac | 18 +++++++++--------- 2 files changed, 19 insertions(+), 20 deletions(-)
Makefile +10 -11
@@ -29,10 +29,10 @@ all:: # Perl-compatible regular expressions instead of standard or extended # POSIX regular expressions. # -# Currently USE_LIBPCRE is a synonym for USE_LIBPCRE1, define -# USE_LIBPCRE2 instead if you'd like to use version 2 of the PCRE -# library. The USE_LIBPCRE flag will likely be changed to mean v2 by -# default in future releases. +# The USE_LIBPCRE flag is a synonym for USE_LIBPCRE2, in previous +# versions it meant the same thing USE_LIBPCRE1 does now. Define +# USE_LIBPCRE1 instead if you'd like to use the legacy version 1 of +# the PCRE library. # # Define LIBPCREDIR=/foo/bar if your PCRE header and library files are in # /foo/bar/include and /foo/bar/lib directories.
@@ -1090,18 +1090,17 @@ ifdef NO_LIBGEN_H COMPAT_OBJS += compat/basename.o endif -USE_LIBPCRE1 ?= $(USE_LIBPCRE) - -ifneq (,$(USE_LIBPCRE1)) - ifdef USE_LIBPCRE2 -$(error Only set USE_LIBPCRE1 (or its alias USE_LIBPCRE) or USE_LIBPCRE2, not both!) - endif +USE_LIBPCRE2 ?= $(USE_LIBPCRE) +ifdef USE_LIBPCRE1 BASIC_CFLAGS += -DUSE_LIBPCRE1 EXTLIBS += -lpcre endif -ifdef USE_LIBPCRE2 +ifneq (,$(USE_LIBPCRE2)) + ifdef USE_LIBPCRE1 +$(error Only set USE_LIBPCRE2 (or its alias USE_LIBPCRE) or USE_LIBPCRE1, not both!) + endif BASIC_CFLAGS += -DUSE_LIBPCRE2 EXTLIBS += -lpcre2-8 endif
configure.ac +9 -9
@@ -255,25 +255,25 @@ GIT_PARSE_WITH([openssl])) # Perl-compatible regular expressions instead of standard or extended # POSIX regular expressions. # -# Currently USE_LIBPCRE is a synonym for USE_LIBPCRE1, define -# USE_LIBPCRE2 instead if you'd like to use version 2 of the PCRE -# library. The USE_LIBPCRE flag will likely be changed to mean v2 by -# default in future releases. +# The USE_LIBPCRE flag is a synonym for USE_LIBPCRE2, in previous +# versions it meant the same thing USE_LIBPCRE1 does now. Define +# USE_LIBPCRE1 instead if you'd like to use the legacy version 1 of +# the PCRE library. # # Define LIBPCREDIR=/foo/bar if your PCRE header and library files are in # /foo/bar/include and /foo/bar/lib directories. # AC_ARG_WITH(libpcre, -AS_HELP_STRING([--with-libpcre],[synonym for --with-libpcre1]), +AS_HELP_STRING([--with-libpcre],[synonym for --with-libpcre2]), if test "$withval" = "no"; then - USE_LIBPCRE1= + USE_LIBPCRE2= elif test "$withval" = "yes"; then - USE_LIBPCRE1=YesPlease + USE_LIBPCRE2=YesPlease else - USE_LIBPCRE1=YesPlease + USE_LIBPCRE2=YesPlease LIBPCREDIR=$withval AC_MSG_NOTICE([Setting LIBPCREDIR to $LIBPCREDIR]) - dnl USE_LIBPCRE1 can still be modified below, so don't substitute + dnl USE_LIBPCRE2 can still be modified below, so don't substitute dnl it yet. GIT_CONF_SUBST([LIBPCREDIR]) fi)
Signature · 1 line
2.11.0