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: reproduce and explain '$...



details:   https://anonhg.NetBSD.org/src/rev/d41c4232cb73
branches:  trunk
changeset: 373731:d41c4232cb73
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sat Feb 25 06:54:08 2023 +0000

description:
tests/make: reproduce and explain '$' in MAKEFLAGS

https://mail-index.netbsd.org/current-users/2023/02/24/msg043633.html

diffstat:

 usr.bin/make/unit-tests/varname-dot-makeflags.exp     |   12 +-
 usr.bin/make/unit-tests/varname-dot-makeflags.mk      |  106 ++++++++++++++++-
 usr.bin/make/unit-tests/varname-dot-makeoverrides.exp |   11 +-
 usr.bin/make/unit-tests/varname-dot-makeoverrides.mk  |   29 ++--
 4 files changed, 133 insertions(+), 25 deletions(-)

diffs (190 lines):

diff -r 03a8490da5a6 -r d41c4232cb73 usr.bin/make/unit-tests/varname-dot-makeflags.exp
--- a/usr.bin/make/unit-tests/varname-dot-makeflags.exp Sat Feb 25 00:40:22 2023 +0000
+++ b/usr.bin/make/unit-tests/varname-dot-makeflags.exp Sat Feb 25 06:54:08 2023 +0000
@@ -1,3 +1,11 @@
-echo "$MAKEFLAGS"
- -r -k -d 00000 -D VARNAME WITH SPACES 
+dollars_stage_0: MAKEFLAGS=< -r -k >
+dollars_stage_1: env MAKEFLAGS=< -r -k DOLLARS=\$\{varname\}>
+dollars_stage_1: MAKEFLAGS=< -r -k DOLLARS=\{varname\}>
+dollars_stage_1: MAKEFLAGS:q=< -r -k DOLLARS=\{varname\}>
+dollars_stage_2: env MAKEFLAGS=< -r -k DOLLARS=>
+dollars_stage_2: dollars=<>
+dollars_stage_2: MAKEFLAGS=< -r -k DOLLARS=>
+dollars_stage_3: env MAKEFLAGS=< -r -k DOLLARS=>
+dollars_stage_3: dollars=<>
+dollars_stage_3: MAKEFLAGS=< -r -k DOLLARS=>
 exit status 0
diff -r 03a8490da5a6 -r d41c4232cb73 usr.bin/make/unit-tests/varname-dot-makeflags.mk
--- a/usr.bin/make/unit-tests/varname-dot-makeflags.mk  Sat Feb 25 00:40:22 2023 +0000
+++ b/usr.bin/make/unit-tests/varname-dot-makeflags.mk  Sat Feb 25 06:54:08 2023 +0000
@@ -1,15 +1,107 @@
-# $NetBSD: varname-dot-makeflags.mk,v 1.1 2020/12/01 20:37:30 rillig Exp $
+# $NetBSD: varname-dot-makeflags.mk,v 1.2 2023/02/25 06:54:08 rillig Exp $
 #
 # Tests for the special .MAKEFLAGS variable, which collects almost all
 # command line arguments and passes them on to any child processes via
 # the environment variable MAKEFLAGS (without leading '.').
+#
+# See also:
+#      varname-dot-makeoverrides.mk
+
+all: dollars_stage_0 #spaces_stage_0 dollars_stage_0 append_stage_0
+
 
 # When options are parsed, the option and its argument are appended as
 # separate words to .MAKEFLAGS.  Special characters in the option argument
-# are not quoted though.  It seems to have not been necessary at least from
-# 1993 until 2020.
-.MAKEFLAGS: -d00000 -D"VARNAME WITH SPACES"
+# are not quoted though.  It seems to have not been necessary since at least
+# 1993.
+spaces_stage_0:
+       @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
+       @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
+       @${MAKE} -f ${MAKEFILE} spaces_stage_1 -d00000 -D"VARNAME WITH SPACES"
+
+# At this point, the 'VARNAME WITH SPACES' is no longer recognizable as a
+# single command line argument.  In practice, variable names don't contain
+# spaces.
+spaces_stage_1:
+       @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
+       @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
+
+# Demonstrate that '$' characters are altered when they are passed on to child
+# make processes via MAKEFLAGS.
+dollars_stage_0:
+       @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
+       # The '$$$$' gets parsed as a literal '$$', making the actual variable
+       # value '$${varname}'.
+       #
+       # When Main_ExportMAKEFLAGS adds the variable DOLLARS to MAKEFLAGS, it
+       # first evaluates the variable value, resulting in '${varname}'.
+       #
+       # This value is then escaped as '\$\{varname\}', to ensure that the
+       # variable is later interpreted as a single shell word.
+       @${MAKE} -f ${MAKEFILE} dollars_stage_1 DOLLARS='$$$${varname}'
+
+# The environment variable 'MAKEFLAGS' now contains the variable assignment
+# 'DOLLARS=\$\{varname\}', including the backslashes.
+#
+# expect: dollars_stage_1: env MAKEFLAGS=< -r -k DOLLARS=\$\{varname\}>
+#
+# When Main_ParseArgLine calls Str_Words to parse the flags from MAKEFLAGS, it
+# removes the backslashes, resulting in the plain variable assignment
+# 'DOLLARS=${varname}'.
+dollars_stage_1:
+       @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
 
-all:
-       echo "$$MAKEFLAGS"
-       @:;
+       # At this point, evaluating the environment variable 'MAKEFLAGS' has
+       # strange side effects, as the string '\$\{varname\}' is interpreted
+       # as:
+       #
+       #       \               a single backslash
+       #       $\              the value of the variable named '\'
+       #       {varname\}      a literal string
+       #
+       # Since the variable name '\' is not defined, the resulting value is
+       # '\{varname\}'.
+       @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
+
+       # The modifier ':q' escapes a '$' in the variable value to '$$', but
+       # it's too late, as that modifier applies after the expression has
+       # been evaluated.
+       @echo '$@: MAKEFLAGS:q=<'${MAKEFLAGS:q}'>'
+
+       # The value of the variable DOLLARS is now '${varname}'.  Since there
+       # is no variable named 'varname', this expression evaluates to ''.
+       @${MAKE} -f ${MAKEFILE} dollars_stage_2
+
+# Uncomment these lines to see the above variable expansions in action.
+#${:U\\}=backslash
+#varname=varvalue
+
+dollars_stage_2:
+       @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
+       @echo '$@: dollars=<'${DOLLARS:Q}'>'
+       @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
+       @${MAKE} -f ${MAKEFILE} dollars_stage_3
+
+dollars_stage_3:
+       @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
+       @echo '$@: dollars=<'${DOLLARS:Uundefined:Q}'>'
+       @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
+
+
+# Demonstrates in which exact order the MAKEFLAGS are built together from the
+# parent MAKEFLAGS and the flags from the command line, in particular that
+# variable assignments are passed at the end, after the options.
+append_stage_0:
+       @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
+       @${MAKE} -Dbefore-0 -f ${MAKEFILE} append_stage_1 VAR0=value -Dafter-0
+
+append_stage_1:
+       @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
+       @${MAKE} -Dbefore-1 -f ${MAKEFILE} append_stage_2 VAR1=value -Dafter-1
+
+append_stage_2:
+       @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
+       @${MAKE} -Dbefore-2 -f ${MAKEFILE} append_stage_3 VAR2=value -Dafter-2
+
+append_stage_3:
+       @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
diff -r 03a8490da5a6 -r d41c4232cb73 usr.bin/make/unit-tests/varname-dot-makeoverrides.exp
--- a/usr.bin/make/unit-tests/varname-dot-makeoverrides.exp     Sat Feb 25 00:40:22 2023 +0000
+++ b/usr.bin/make/unit-tests/varname-dot-makeoverrides.exp     Sat Feb 25 06:54:08 2023 +0000
@@ -1,5 +1,8 @@
-make -r -f varname-dot-makeoverrides.mk dollars_stage_2 DOLLARS='$${varname}'
-stage 2: dollars=<${varname}>
-make -r -f varname-dot-makeoverrides.mk dollars_stage_3
-stage 3: dollars=<>
+all: overrides=<>
+make -f varname-dot-makeoverrides.mk stage_1 VAR=value
+stage_1: overrides=< VAR>
+make -f varname-dot-makeoverrides.mk stage_2
+stage_2: overrides=< VAR>
+make -f varname-dot-makeoverrides.mk stage_3
+stage_3: overrides=< VAR>
 exit status 0
diff -r 03a8490da5a6 -r d41c4232cb73 usr.bin/make/unit-tests/varname-dot-makeoverrides.mk
--- a/usr.bin/make/unit-tests/varname-dot-makeoverrides.mk      Sat Feb 25 00:40:22 2023 +0000
+++ b/usr.bin/make/unit-tests/varname-dot-makeoverrides.mk      Sat Feb 25 06:54:08 2023 +0000
@@ -1,18 +1,23 @@
-# $NetBSD: varname-dot-makeoverrides.mk,v 1.4 2023/02/25 00:09:52 rillig Exp $
+# $NetBSD: varname-dot-makeoverrides.mk,v 1.5 2023/02/25 06:54:08 rillig Exp $
 #
-# Tests for the special .MAKEOVERRIDES variable.
+# Tests for the special .MAKEOVERRIDES variable, which lists the names of the
+# variables that are passed on to child processes via the MAKEFLAGS
+# environment variable.
+#
+# See also:
+#      varname-dot-makeflags.mk
 
 all:
-       @${MAKE} -r -f ${MAKEFILE} dollars_stage_1
+       @echo '$@: overrides=<'${.MAKEOVERRIDES:Uundefined:Q}'>'
+       ${MAKE} -f ${MAKEFILE} stage_1 VAR=value
 
-# Demonstrate that '$' characters are altered when they are passed on to child
-# make processes via .MAKEOVERRIDES and MAKEFLAGS.
-dollars_stage_1:
-       ${MAKE} -r -f ${MAKEFILE} dollars_stage_2 DOLLARS='$$$${varname}'
+stage_1:
+       @echo '$@: overrides=<'${.MAKEOVERRIDES:Q}'>'
+       ${MAKE} -f ${MAKEFILE} stage_2
 
-dollars_stage_2:
-       @echo 'stage 2: dollars=<${DOLLARS}>'
-       ${MAKE} -r -f ${MAKEFILE} dollars_stage_3
+stage_2:
+       @echo '$@: overrides=<'${.MAKEOVERRIDES:Q}'>'
+       ${MAKE} -f ${MAKEFILE} stage_3
 
-dollars_stage_3:
-       @echo 'stage 3: dollars=<${DOLLARS}>'
+stage_3:
+       @echo '$@: overrides=<'${.MAKEOVERRIDES:Q}'>'



Home | Main Index | Thread Index | Old Index