xref: /freebsd/contrib/bmake/unit-tests/var-op-default.mk (revision 06b9b3e0ad0dc3f0166b3e8f26ced68c271cf527)
1*06b9b3e0SSimon J. Gerraty# $NetBSD: var-op-default.mk,v 1.3 2020/12/07 21:35:43 rillig Exp $
22c3632d1SSimon J. Gerraty#
32c3632d1SSimon J. Gerraty# Tests for the ?= variable assignment operator, which only assigns
42c3632d1SSimon J. Gerraty# if the variable is still undefined.
52c3632d1SSimon J. Gerraty
6*06b9b3e0SSimon J. Gerraty# The variable VAR is not defined yet.  Therefore it gets the default value
7*06b9b3e0SSimon J. Gerraty# from the variable assignment.
8*06b9b3e0SSimon J. GerratyVAR?=		default value
9*06b9b3e0SSimon J. Gerraty.if ${VAR} != "default value"
10*06b9b3e0SSimon J. Gerraty.  error
11*06b9b3e0SSimon J. Gerraty.endif
12*06b9b3e0SSimon J. Gerraty
13*06b9b3e0SSimon J. Gerraty# At this point, the variable 'VAR' is already defined.  The '?=' therefore
14*06b9b3e0SSimon J. Gerraty# ignores the new variable value, preserving the previous "default value".
15*06b9b3e0SSimon J. GerratyVAR?=		ignored
16*06b9b3e0SSimon J. Gerraty.if ${VAR} != "default value"
17*06b9b3e0SSimon J. Gerraty.  error
18*06b9b3e0SSimon J. Gerraty.endif
19*06b9b3e0SSimon J. Gerraty
20*06b9b3e0SSimon J. Gerraty# The '?=' operator only checks whether the variable is defined or not.
21*06b9b3e0SSimon J. Gerraty# An empty variable is defined, therefore the '?=' operator does nothing.
22*06b9b3e0SSimon J. GerratyEMPTY=		# empty
23*06b9b3e0SSimon J. GerratyEMPTY?=		ignored
24*06b9b3e0SSimon J. Gerraty.if ${EMPTY} != ""
25*06b9b3e0SSimon J. Gerraty.  error
26*06b9b3e0SSimon J. Gerraty.endif
27*06b9b3e0SSimon J. Gerraty
28*06b9b3e0SSimon J. Gerraty# The .for loop is described in the manual page as if it would operate on
29*06b9b3e0SSimon J. Gerraty# variables.  This is not entirely true.  Instead, each occurrence of an
30*06b9b3e0SSimon J. Gerraty# expression $i or ${i} or ${i:...} is substituted with ${:Uloop-value}.
31*06b9b3e0SSimon J. Gerraty# This comes very close to the description, the only difference is that
32*06b9b3e0SSimon J. Gerraty# there is never an actual variable named 'i' involved.
33*06b9b3e0SSimon J. Gerraty#
34*06b9b3e0SSimon J. Gerraty# Because there is not really a variable named 'i', the '?=' operator
35*06b9b3e0SSimon J. Gerraty# performs the variable assignment, resulting in $i == "default".
36*06b9b3e0SSimon J. Gerraty.for i in loop-value
37*06b9b3e0SSimon J. Gerratyi?=		default
38*06b9b3e0SSimon J. Gerraty.endfor
39*06b9b3e0SSimon J. Gerraty.if ${i} != "default"
40*06b9b3e0SSimon J. Gerraty.  error
41*06b9b3e0SSimon J. Gerraty.endif
42*06b9b3e0SSimon J. Gerraty
43*06b9b3e0SSimon J. Gerraty# At the point where the '?=' operator checks whether the variable exists,
44*06b9b3e0SSimon J. Gerraty# it expands the variable name exactly once.  Therefore both 'VAR.param'
45*06b9b3e0SSimon J. Gerraty# and 'VAR.${param}' expand to 'VAR.param', and the second '?=' assignment
46*06b9b3e0SSimon J. Gerraty# has no effect.
47*06b9b3e0SSimon J. Gerraty#
48*06b9b3e0SSimon J. Gerraty# Since 2000.05.11.07.43.42 it has been possible to use nested variable
49*06b9b3e0SSimon J. Gerraty# expressions in variable names, which made make much more versatile.
50*06b9b3e0SSimon J. Gerraty# On 2008.03.31.00.12.21, this particular case of the '?=' operator has been
51*06b9b3e0SSimon J. Gerraty# fixed.  Before, the '?=' operator had not expanded the variable name
52*06b9b3e0SSimon J. Gerraty# 'VAR.${:Uparam}' to see whether the variable already existed.  Since that
53*06b9b3e0SSimon J. Gerraty# variable didn't exist (and variables with '$' in their name are particularly
54*06b9b3e0SSimon J. Gerraty# fragile), the variable assignment with "not used" was performed, and only
55*06b9b3e0SSimon J. Gerraty# during that, the variable name was expanded.
56*06b9b3e0SSimon J. GerratyVAR.param=		already defined
57*06b9b3e0SSimon J. GerratyVAR.${:Uparam}?=	not used
58*06b9b3e0SSimon J. Gerraty.if ${VAR.param} != "already defined"
59*06b9b3e0SSimon J. Gerraty.  error
60*06b9b3e0SSimon J. Gerraty.endif
61*06b9b3e0SSimon J. Gerraty
62*06b9b3e0SSimon J. Gerraty# Now demonstrate that the variable name is indeed expanded exactly once.
63*06b9b3e0SSimon J. Gerraty# This is tricky to measure correctly since there are many inconsistencies
64*06b9b3e0SSimon J. Gerraty# in and around the code that expands variable expressions in the various
65*06b9b3e0SSimon J. Gerraty# places where variable expressions can occur.  If in doubt, enable the
66*06b9b3e0SSimon J. Gerraty# following debug flags to see what happens:
67*06b9b3e0SSimon J. Gerraty#.MAKEFLAGS: -dcpv
68*06b9b3e0SSimon J. GerratyEXPAND_NAME=		EXPAND.$$$$	# The full variable name is EXPAND.$$
69*06b9b3e0SSimon J. GerratyPARAM=			$$$$
70*06b9b3e0SSimon J. GerratyEXPAND.${PARAM}?=	value with param
71*06b9b3e0SSimon J. Gerraty.if ${${EXPAND_NAME}} != "value with param"
72*06b9b3e0SSimon J. Gerraty.  error
73*06b9b3e0SSimon J. Gerraty.endif
74*06b9b3e0SSimon J. Gerraty.MAKEFLAGS: -d0
752c3632d1SSimon J. Gerraty
762c3632d1SSimon J. Gerratyall:
772c3632d1SSimon J. Gerraty	@:;
78