Subject: Re: [PATCH v6 7/7] grep: simplify config parsing and option parsing

From: Junio C Hamano <[email-masked]>
Date: Mon, 27 Dec 2021 10:51:00 -0800

Junio C Hamano <[email-masked]> writes:

> The above does not look correct at all.
>
> What happens when the configuration parser sees these configuration
> variables in this sequence:
>
>  - grep.patternType set to say "pcre" (or anything not "default").
>  - grep.extendedRegexp set to "true".
>  - grep.patternType set to "default".
>
> After these three variable definitions with the usual "last one
> wins" (for each variable independently), the last value for the
> grep.patternType variable is "default", and the last value for
> the grep.extendedRegexp variable is "true".  The user wants to use
> the ERE patterns.

By the way, the example I gave you for the previous round, and
similarly the one in the message I am responding to were all written
to help you realize that it is simply a broken approach if we do not
keep "default" as default and instead resolve it to either "basic"
or "extended" too early.  The goal of these examples was *NOT* to
tell you "this single thing is broken with the code in this round so
let's fix it".

It seems I am not succeeding in conveying that point, and specially
I smell that in the change between v5 and v6.

So let me try to be a bit more explicit.  Let's not do another round
of "I think this is a moral equivalent of what you want, even though
it is not done the way you suggested." I think we wasted a reroll or
three with that attitude in changes leading to v6 already, after I
gave my review to v5, and I think the v5 review essentially was a
repeat of my review for v3's 3/7, so if I conveyed the point clearly
enough back then, perhaps we didn't have to waste your time on v4
and v5, either.  Sorry about that.

So, here is what this step of the series SHOULD do:

 * Use two members to keep track of the final configuration value we
   saw for grep.patternTYpe and grep.extendedRegexp independently.
   The existing .fixed and .pcre2 fields are superfluous.  But no
   more "ah, we see patternType so let's ignore extendedRegexp"
   games.

 * When parsing the command line options -G, -E, etc., update the
   .patternType member with the value found.  We do not want to and
   need to touch .extendedRegexp member, whose SOLE purpose should
   be to keep track of "what the last value we saw for
   grep.extendedRegexp configuration variable".

 * Do ALL THE ABOVE while keeping "default" in the .patternType
   member as "default" as-is given by the user; do not turn it into
   "basic" or "extended" in config callback at all.

 * At some point of your choice between the time we finished parsing
   both configuration variables and command line options and the
   time we compile the pattern string to regexp objects of various
   types, look at the .patternType member and resolve it into
   basic/extended IFF it is set to default, using .extendedRegexp
   member (for this to work correctly, it is important not to let
   -E/-G command like options to touch .extendedRegexp member---it
   should be used ONLY to keep track of "what the last value we saw
   for grep.extendedRegexp configuration variable").

 * After the above step is done, .extendedRegexp member is no longer
   needed and we can compile the pattern using only the value in
   .patternType member.

The penultimate bullet point gives us a wiggle room to lose the
"commit" thing and delay it until the very last moment, the function
that decides to call which regexp engine's regcomp.  The important
thing is that we cannot lose the value "default" from .patternType
field or lose the last value given to .extendedRegexp field too
early, namely, before we have read all the configurtion streams and
know the last value for these two variables.

Thanks.  Hopefully I was clear enough this time.

----- >8 ---- ----- >8 ---- ----- >8 ---- ----- >8 ---- ----- >8 -----
Subject: [PATCH] fixup! grep tests: add missing "grep.patternType" config tests

---
 t/t7810-grep.sh | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 664f884e12..2e2829ee55 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -471,6 +471,16 @@ do
 		test_cmp expected actual
 	'
 
+	test_expect_success "grep $L with grep.extendedRegexp and grep.patternType are both last-one-wins independently" '
+		echo "${HC}ab:abc" >expected &&
+		git \
+			-c grep.patternType=fixed \
+			-c grep.extendedRegexp=true \
+			-c grep.patternType=default \
+			grep "a+b*c" $H ab >actual &&
+		test_cmp expected actual
+	'
+
 	test_expect_success "grep $L with grep.patternType=extended and grep.patternType=default" '
 		echo "${HC}ab:a+bc" >expected &&
 		git \
-- 
2.34.1-568-g69e9fd72b5