Module Name: src
Committed By: rillig
Date: Sun Nov 8 18:05:32 UTC 2020
Modified Files:
src/usr.bin/make/unit-tests: varmod-loop.exp varmod-loop.mk
Log Message:
make(1): add test demonstrating how ':=' and ':@var@' interact
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/usr.bin/make/unit-tests/varmod-loop.exp
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/make/unit-tests/varmod-loop.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/make/unit-tests/varmod-loop.exp
diff -u src/usr.bin/make/unit-tests/varmod-loop.exp:1.3 src/usr.bin/make/unit-tests/varmod-loop.exp:1.4
--- src/usr.bin/make/unit-tests/varmod-loop.exp:1.3 Sun Sep 13 07:32:32 2020
+++ src/usr.bin/make/unit-tests/varmod-loop.exp Sun Nov 8 18:05:32 2020
@@ -1,3 +1,11 @@
+ParseReadLine (115): 'USE_8_DOLLARS= ${:U1:@var@${8_DOLLARS}@} ${8_DOLLARS} $$$$$$$$'
+CondParser_Eval: ${USE_8_DOLLARS} != "\$\$\$\$ \$\$\$\$ \$\$\$\$"
+lhs = "$$$$ $$$$ $$$$", rhs = "$$$$ $$$$ $$$$", op = !=
+ParseReadLine (120): 'SUBST_CONTAINING_LOOP:= ${USE_8_DOLLARS}'
+CondParser_Eval: ${SUBST_CONTAINING_LOOP} != "\$\$ \$\$\$\$ \$\$\$\$"
+lhs = "$$ $$$$ $$$$", rhs = "$$ $$$$ $$$$", op = !=
+ParseReadLine (145): '.MAKEFLAGS: -d0'
+ParseDoDependency(.MAKEFLAGS: -d0)
:+one+ +two+ +three+:
:x1y x2y x3y:
:x1y x2y x3y:
Index: src/usr.bin/make/unit-tests/varmod-loop.mk
diff -u src/usr.bin/make/unit-tests/varmod-loop.mk:1.6 src/usr.bin/make/unit-tests/varmod-loop.mk:1.7
--- src/usr.bin/make/unit-tests/varmod-loop.mk:1.6 Tue Nov 3 18:21:36 2020
+++ src/usr.bin/make/unit-tests/varmod-loop.mk Sun Nov 8 18:05:32 2020
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-loop.mk,v 1.6 2020/11/03 18:21:36 rillig Exp $
+# $NetBSD: varmod-loop.mk,v 1.7 2020/11/08 18:05:32 rillig Exp $
#
# Tests for the :@var@...${var}...@ variable modifier.
@@ -100,3 +100,46 @@ mod-loop-dollar:
.if defined(var)
. error
.endif
+
+# Assignment using the ':=' operator, combined with the :@var@ modifier
+#
+8_DOLLARS= $$$$$$$$
+# This string literal is written with 8 dollars, and this is saved as the
+# variable value. But as soon as this value is evaluated, it goes through
+# Var_Subst, which replaces each '$$' with a single '$'. This could be
+# prevented by VARE_KEEP_DOLLAR, but that flag is usually removed before
+# expanding subexpressions. See ApplyModifier_Loop and ParseModifierPart
+# for examples.
+#
+.MAKEFLAGS: -dcp
+USE_8_DOLLARS= ${:U1:@var@${8_DOLLARS}@} ${8_DOLLARS} $$$$$$$$
+.if ${USE_8_DOLLARS} != "\$\$\$\$ \$\$\$\$ \$\$\$\$"
+. error
+.endif
+#
+SUBST_CONTAINING_LOOP:= ${USE_8_DOLLARS}
+# The ':=' assignment operator evaluates the variable value using the flag
+# VARE_KEEP_DOLLAR, which means that some dollar signs are preserved, but not
+# all. The dollar signs in the top-level expression and in the indirect
+# ${8_DOLLARS} are preserved.
+#
+# The variable modifier :@var@ does not preserve the dollar signs though, no
+# matter in which context it is evaluated. What happens in detail is:
+# First, the modifier part "${8_DOLLARS}" is parsed without expanding it.
+# Next, each word of the value is expanded on its own, and at this moment
+# in ApplyModifier_Loop, the VARE_KEEP_DOLLAR flag is not passed down to
+# ModifyWords, resulting in "$$$$" for the first word of USE_8_DOLLARS.
+#
+# The remaining words of USE_8_DOLLARS are not affected by any variable
+# modifier and are thus expanded with the flag VARE_KEEP_DOLLAR in action.
+# The variable SUBST_CONTAINING_LOOP therefore gets assigned the raw value
+# "$$$$ $$$$$$$$ $$$$$$$$".
+#
+# The variable expression in the condition then expands this raw stored value
+# once, resulting in "$$ $$$$ $$$$". The effects from VARE_KEEP_DOLLAR no
+# longer take place since they had only been active during the evaluation of
+# the variable assignment.
+.if ${SUBST_CONTAINING_LOOP} != "\$\$ \$\$\$\$ \$\$\$\$"
+. error
+.endif
+.MAKEFLAGS: -d0