summaryrefslogtreecommitdiff
path: root/unit-tests/varmod-loop.mk
diff options
context:
space:
mode:
Diffstat (limited to 'unit-tests/varmod-loop.mk')
-rw-r--r--unit-tests/varmod-loop.mk49
1 files changed, 47 insertions, 2 deletions
diff --git a/unit-tests/varmod-loop.mk b/unit-tests/varmod-loop.mk
index a3fbbfceae8d..654c449d7bfa 100644
--- a/unit-tests/varmod-loop.mk
+++ b/unit-tests/varmod-loop.mk
@@ -1,7 +1,9 @@
-# $NetBSD: varmod-loop.mk,v 1.5 2020/10/31 12:34:03 rillig Exp $
+# $NetBSD: varmod-loop.mk,v 1.8 2020/11/12 00:40:55 rillig Exp $
#
# Tests for the :@var@...${var}...@ variable modifier.
+.MAKE.SAVE_DOLLARS= yes
+
all: mod-loop-varname
all: mod-loop-resolve
all: mod-loop-varname-dollar
@@ -57,7 +59,7 @@ mod-loop-varname-dollar:
@echo $@:${1 2 3:L:@v$$@($v)@:Q}.
@echo $@:${1 2 3:L:@v$$$@($v)@:Q}.
-# Demonstrate that it is possible to generate dollar characters using the
+# Demonstrate that it is possible to generate dollar signs using the
# :@ modifier.
#
# These are edge cases that could have resulted in a parse error as well
@@ -100,3 +102,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