Module Name: src
Committed By: rillig
Date: Mon Dec 7 21:35:43 UTC 2020
Modified Files:
src/distrib/sets/lists/tests: mi
src/usr.bin/make/unit-tests: Makefile var-op-default.mk
Removed Files:
src/usr.bin/make/unit-tests: qequals.exp qequals.mk
Log Message:
make(1): add tests and tutorial for the ?= assignment operator
To generate a diff of this commit:
cvs rdiff -u -r1.984 -r1.985 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.238 -r1.239 src/usr.bin/make/unit-tests/Makefile
cvs rdiff -u -r1.1 -r0 src/usr.bin/make/unit-tests/qequals.exp
cvs rdiff -u -r1.3 -r0 src/usr.bin/make/unit-tests/qequals.mk
cvs rdiff -u -r1.2 -r1.3 src/usr.bin/make/unit-tests/var-op-default.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.984 src/distrib/sets/lists/tests/mi:1.985
--- src/distrib/sets/lists/tests/mi:1.984 Mon Dec 7 07:51:25 2020
+++ src/distrib/sets/lists/tests/mi Mon Dec 7 21:35:43 2020
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.984 2020/12/07 07:51:25 rillig Exp $
+# $NetBSD: mi,v 1.985 2020/12/07 21:35:43 rillig Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -5263,8 +5263,8 @@
./usr/tests/usr.bin/make/unit-tests/posix.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/posix1.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/posix1.mk tests-usr.bin-tests compattestfile,atf
-./usr/tests/usr.bin/make/unit-tests/qequals.exp tests-usr.bin-tests compattestfile,atf
-./usr/tests/usr.bin/make/unit-tests/qequals.mk tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/qequals.exp tests-obsolete obsolete,atf
+./usr/tests/usr.bin/make/unit-tests/qequals.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/unit-tests/recursive.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/recursive.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-dots.exp tests-usr.bin-tests compattestfile,atf
Index: src/usr.bin/make/unit-tests/Makefile
diff -u src/usr.bin/make/unit-tests/Makefile:1.238 src/usr.bin/make/unit-tests/Makefile:1.239
--- src/usr.bin/make/unit-tests/Makefile:1.238 Mon Dec 7 01:32:04 2020
+++ src/usr.bin/make/unit-tests/Makefile Mon Dec 7 21:35:43 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.238 2020/12/07 01:32:04 rillig Exp $
+# $NetBSD: Makefile,v 1.239 2020/12/07 21:35:43 rillig Exp $
#
# Unit tests for make(1)
#
@@ -257,7 +257,6 @@ TESTS+= parse-var
TESTS+= phony-end
TESTS+= posix
TESTS+= # posix1 # broken by reverting POSIX changes
-TESTS+= qequals
TESTS+= recursive
TESTS+= sh
TESTS+= sh-dots
Index: src/usr.bin/make/unit-tests/var-op-default.mk
diff -u src/usr.bin/make/unit-tests/var-op-default.mk:1.2 src/usr.bin/make/unit-tests/var-op-default.mk:1.3
--- src/usr.bin/make/unit-tests/var-op-default.mk:1.2 Sun Aug 16 14:25:16 2020
+++ src/usr.bin/make/unit-tests/var-op-default.mk Mon Dec 7 21:35:43 2020
@@ -1,9 +1,77 @@
-# $NetBSD: var-op-default.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
+# $NetBSD: var-op-default.mk,v 1.3 2020/12/07 21:35:43 rillig Exp $
#
# Tests for the ?= variable assignment operator, which only assigns
# if the variable is still undefined.
-# TODO: Implementation
+# The variable VAR is not defined yet. Therefore it gets the default value
+# from the variable assignment.
+VAR?= default value
+.if ${VAR} != "default value"
+. error
+.endif
+
+# At this point, the variable 'VAR' is already defined. The '?=' therefore
+# ignores the new variable value, preserving the previous "default value".
+VAR?= ignored
+.if ${VAR} != "default value"
+. error
+.endif
+
+# The '?=' operator only checks whether the variable is defined or not.
+# An empty variable is defined, therefore the '?=' operator does nothing.
+EMPTY= # empty
+EMPTY?= ignored
+.if ${EMPTY} != ""
+. error
+.endif
+
+# The .for loop is described in the manual page as if it would operate on
+# variables. This is not entirely true. Instead, each occurrence of an
+# expression $i or ${i} or ${i:...} is substituted with ${:Uloop-value}.
+# This comes very close to the description, the only difference is that
+# there is never an actual variable named 'i' involved.
+#
+# Because there is not really a variable named 'i', the '?=' operator
+# performs the variable assignment, resulting in $i == "default".
+.for i in loop-value
+i?= default
+.endfor
+.if ${i} != "default"
+. error
+.endif
+
+# At the point where the '?=' operator checks whether the variable exists,
+# it expands the variable name exactly once. Therefore both 'VAR.param'
+# and 'VAR.${param}' expand to 'VAR.param', and the second '?=' assignment
+# has no effect.
+#
+# Since 2000.05.11.07.43.42 it has been possible to use nested variable
+# expressions in variable names, which made make much more versatile.
+# On 2008.03.31.00.12.21, this particular case of the '?=' operator has been
+# fixed. Before, the '?=' operator had not expanded the variable name
+# 'VAR.${:Uparam}' to see whether the variable already existed. Since that
+# variable didn't exist (and variables with '$' in their name are particularly
+# fragile), the variable assignment with "not used" was performed, and only
+# during that, the variable name was expanded.
+VAR.param= already defined
+VAR.${:Uparam}?= not used
+.if ${VAR.param} != "already defined"
+. error
+.endif
+
+# Now demonstrate that the variable name is indeed expanded exactly once.
+# This is tricky to measure correctly since there are many inconsistencies
+# in and around the code that expands variable expressions in the various
+# places where variable expressions can occur. If in doubt, enable the
+# following debug flags to see what happens:
+#.MAKEFLAGS: -dcpv
+EXPAND_NAME= EXPAND.$$$$ # The full variable name is EXPAND.$$
+PARAM= $$$$
+EXPAND.${PARAM}?= value with param
+.if ${${EXPAND_NAME}} != "value with param"
+. error
+.endif
+.MAKEFLAGS: -d0
all:
@:;