Source-Changes-HG archive

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

[src/trunk]: src/usr.bin/make/unit-tests tests/make: document why ':?' cannot...



details:   https://anonhg.NetBSD.org/src/rev/9bbfca6e4d7d
branches:  trunk
changeset: 373581:9bbfca6e4d7d
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sat Feb 18 18:23:58 2023 +0000

description:
tests/make: document why ':?' cannot parse its operands in balanced mode

diffstat:

 usr.bin/make/unit-tests/varmod-ifelse.exp |   7 +++
 usr.bin/make/unit-tests/varmod-ifelse.mk  |  66 ++++++++++++++++++++++++++++++-
 2 files changed, 72 insertions(+), 1 deletions(-)

diffs (94 lines):

diff -r b6614dd3df25 -r 9bbfca6e4d7d usr.bin/make/unit-tests/varmod-ifelse.exp
--- a/usr.bin/make/unit-tests/varmod-ifelse.exp Sat Feb 18 15:21:34 2023 +0000
+++ b/usr.bin/make/unit-tests/varmod-ifelse.exp Sat Feb 18 18:23:58 2023 +0000
@@ -27,6 +27,13 @@
 make: "varmod-ifelse.mk" line 169: false
 make: Bad conditional expression '     ' in '  ?true:false'
 make: "varmod-ifelse.mk" line 171: 
+CondParser_Eval: 0 && ${1:?${:Uthen0:S,}},,}:${:Uelse0:S,}},,}} != "not evaluated"
+CondParser_Eval: 1 && ${0:?${:Uthen1:S,}},,}:${:Uelse1:S,}},,}} != "else1"
+CondParser_Eval: 0
+Comparing "else1" != "else1"
+CondParser_Eval: 2 && ${1:?${:Uthen2:S,}},,}:${:Uelse2:S,}},,}} != "then2"
+CondParser_Eval: 1
+Comparing "then2" != "then2"
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1
diff -r b6614dd3df25 -r 9bbfca6e4d7d usr.bin/make/unit-tests/varmod-ifelse.mk
--- a/usr.bin/make/unit-tests/varmod-ifelse.mk  Sat Feb 18 15:21:34 2023 +0000
+++ b/usr.bin/make/unit-tests/varmod-ifelse.mk  Sat Feb 18 18:23:58 2023 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-ifelse.mk,v 1.20 2022/09/25 12:51:37 rillig Exp $
+# $NetBSD: varmod-ifelse.mk,v 1.21 2023/02/18 18:23:58 rillig Exp $
 #
 # Tests for the ${cond:?then:else} variable modifier, which evaluates either
 # the then-expression or the else-expression, depending on the condition.
@@ -182,3 +182,67 @@
   "1:not_prime 2:prime 3:prime 4:not_prime 5:prime"
 .  error
 .endif
+
+# When parsing the modifier ':?', there are 3 possible cases:
+#
+#      1. The whole expression is only parsed.
+#      2. The expression is parsed and the 'then' branch is evaluated.
+#      3. The expression is parsed and the 'else' branch is evaluated.
+#
+# In all of these cases, the expression must be parsed in the same way,
+# especially when one of the branches contains unbalanced '{}' braces.
+#
+# At 2020-01-01, the expressions from the 'then' and 'else' branches were
+# parsed differently, depending on whether the branch was taken or not.  When
+# the branch was taken, the parser recognized that in the modifier ':S,}},,',
+# the '}}' were ordinary characters.  When the branch was not taken, the
+# parser only counted balanced '{' and '}', ignoring any escaping or other
+# changes in the interpretation.
+#
+# In var.c 1.285 from 2020-07-20, the parsing of the expressions changed so
+# that in both cases the expression is parsed in the same way, taking the
+# unbalanced braces in the ':S' modifiers into account.  This change was not
+# on purpose, the commit message mentioned 'has the same effect', which was a
+# wrong assumption.
+#
+# In var.c 1.323 from 2020-07-26, the unintended fix from var.c 1.285 was
+# reverted, still not knowing about the difference between regular parsing and
+# balanced-mode parsing.
+#
+# In var.c 1.1028 from 2022-08-08, there was another attempt at fixing this
+# inconsistency in parsing, but since that broke parsing of the modifier ':@',
+# it was reverted in var.c 1.1029 from 2022-08-23.
+#
+# In var.c 1.1047 from 2023-02-18, the inconsistency in parsing was finally
+# fixed.  The modifier ':@' now parses the body in balanced mode, while
+# everywhere else the modifier parts have their subexpressions parsed in the
+# same way, no matter whether they are evaluated or not.
+#
+# The modifiers ':@' and ':?' are similar in that they conceptually contain
+# text to be evaluated later or conditionally, still they parse that text
+# differently.  The crucial difference is that the body of the modifier ':@'
+# is always parsed using balanced mode.  The modifier ':?', on the other hand,
+# must parse both of its branches in the same way, no matter whether they are
+# evaluated or not.  Since balanced mode and standard mode are incompatible,
+# it's impossible to use balanced mode in the modifier ':?'.
+.MAKEFLAGS: -dc
+.if 0 && ${1:?${:Uthen0:S,}},,}:${:Uelse0:S,}},,}} != "not evaluated"
+# At 2020-01-07, the expression evaluated to 'then0,,}}', even though it was
+# irrelevant as the '0' had already been evaluated to 'false'.
+.  error
+.endif
+.if 1 && ${0:?${:Uthen1:S,}},,}:${:Uelse1:S,}},,}} != "else1"
+.  error
+.endif
+.if 2 && ${1:?${:Uthen2:S,}},,}:${:Uelse2:S,}},,}} != "then2"
+# At 2020-01-07, the whole expression evaluated to 'then2,,}}' instead of the
+# expected 'then2'.  The 'then' branch of the ':?' modifier was parsed
+# normally, parsing and evaluating the ':S' modifier, thereby treating the
+# '}}' as ordinary characters and resulting in 'then2'.  The 'else' branch was
+# parsed in balanced mode, ignoring that the inner '}}' were ordinary
+# characters.  The '}}' were thus interpreted as the end of the 'else' branch
+# and the whole expression.  This left the trailing ',,}}', which together
+# with the 'then2' formed the result 'then2,,}}'.
+.  error
+.endif
+.MAKEFLAGS: -d0



Home | Main Index | Thread Index | Old Index