1*d5e0a182SSimon J. Gerraty# $NetBSD: var-op-default.mk,v 1.5 2023/11/19 22:32:44 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 606b9b3e0SSimon J. Gerraty# The variable VAR is not defined yet. Therefore it gets the default value 706b9b3e0SSimon J. Gerraty# from the variable assignment. 806b9b3e0SSimon J. GerratyVAR?= default value 906b9b3e0SSimon J. Gerraty.if ${VAR} != "default value" 1006b9b3e0SSimon J. Gerraty. error 1106b9b3e0SSimon J. Gerraty.endif 1206b9b3e0SSimon J. Gerraty 1306b9b3e0SSimon J. Gerraty# At this point, the variable 'VAR' is already defined. The '?=' therefore 1406b9b3e0SSimon J. Gerraty# ignores the new variable value, preserving the previous "default value". 1506b9b3e0SSimon J. GerratyVAR?= ignored 1606b9b3e0SSimon J. Gerraty.if ${VAR} != "default value" 1706b9b3e0SSimon J. Gerraty. error 1806b9b3e0SSimon J. Gerraty.endif 1906b9b3e0SSimon J. Gerraty 2006b9b3e0SSimon J. Gerraty# The '?=' operator only checks whether the variable is defined or not. 2106b9b3e0SSimon J. Gerraty# An empty variable is defined, therefore the '?=' operator does nothing. 2206b9b3e0SSimon J. GerratyEMPTY= # empty 2306b9b3e0SSimon J. GerratyEMPTY?= ignored 2406b9b3e0SSimon J. Gerraty.if ${EMPTY} != "" 2506b9b3e0SSimon J. Gerraty. error 2606b9b3e0SSimon J. Gerraty.endif 2706b9b3e0SSimon J. Gerraty 2806b9b3e0SSimon J. Gerraty# The .for loop is described in the manual page as if it would operate on 2906b9b3e0SSimon J. Gerraty# variables. This is not entirely true. Instead, each occurrence of an 3006b9b3e0SSimon J. Gerraty# expression $i or ${i} or ${i:...} is substituted with ${:Uloop-value}. 3106b9b3e0SSimon J. Gerraty# This comes very close to the description, the only difference is that 3206b9b3e0SSimon J. Gerraty# there is never an actual variable named 'i' involved. 3306b9b3e0SSimon J. Gerraty# 3406b9b3e0SSimon J. Gerraty# Because there is not really a variable named 'i', the '?=' operator 3506b9b3e0SSimon J. Gerraty# performs the variable assignment, resulting in $i == "default". 3606b9b3e0SSimon J. Gerraty.for i in loop-value 3706b9b3e0SSimon J. Gerratyi?= default 3806b9b3e0SSimon J. Gerraty.endfor 3906b9b3e0SSimon J. Gerraty.if ${i} != "default" 4006b9b3e0SSimon J. Gerraty. error 4106b9b3e0SSimon J. Gerraty.endif 4206b9b3e0SSimon J. Gerraty 4306b9b3e0SSimon J. Gerraty# At the point where the '?=' operator checks whether the variable exists, 4406b9b3e0SSimon J. Gerraty# it expands the variable name exactly once. Therefore both 'VAR.param' 4506b9b3e0SSimon J. Gerraty# and 'VAR.${param}' expand to 'VAR.param', and the second '?=' assignment 4606b9b3e0SSimon J. Gerraty# has no effect. 4706b9b3e0SSimon J. Gerraty# 48*d5e0a182SSimon J. Gerraty# Since 2000.05.11.07.43.42 it has been possible to use nested 4906b9b3e0SSimon J. Gerraty# expressions in variable names, which made make much more versatile. 5006b9b3e0SSimon J. Gerraty# On 2008.03.31.00.12.21, this particular case of the '?=' operator has been 5106b9b3e0SSimon J. Gerraty# fixed. Before, the '?=' operator had not expanded the variable name 5206b9b3e0SSimon J. Gerraty# 'VAR.${:Uparam}' to see whether the variable already existed. Since that 5306b9b3e0SSimon J. Gerraty# variable didn't exist (and variables with '$' in their name are particularly 5406b9b3e0SSimon J. Gerraty# fragile), the variable assignment with "not used" was performed, and only 5506b9b3e0SSimon J. Gerraty# during that, the variable name was expanded. 5606b9b3e0SSimon J. GerratyVAR.param= already defined 5706b9b3e0SSimon J. GerratyVAR.${:Uparam}?= not used 5806b9b3e0SSimon J. Gerraty.if ${VAR.param} != "already defined" 5906b9b3e0SSimon J. Gerraty. error 6006b9b3e0SSimon J. Gerraty.endif 6106b9b3e0SSimon J. Gerraty 6206b9b3e0SSimon J. Gerraty# Now demonstrate that the variable name is indeed expanded exactly once. 6306b9b3e0SSimon J. Gerraty# This is tricky to measure correctly since there are many inconsistencies 64*d5e0a182SSimon J. Gerraty# in and around the code that expands expressions in the various 65*d5e0a182SSimon J. Gerraty# places where expressions can occur. If in doubt, enable the 6606b9b3e0SSimon J. Gerraty# following debug flags to see what happens: 6706b9b3e0SSimon J. Gerraty#.MAKEFLAGS: -dcpv 6806b9b3e0SSimon J. GerratyEXPAND_NAME= EXPAND.$$$$ # The full variable name is EXPAND.$$ 6906b9b3e0SSimon J. GerratyPARAM= $$$$ 7006b9b3e0SSimon J. GerratyEXPAND.${PARAM}?= value with param 7106b9b3e0SSimon J. Gerraty.if ${${EXPAND_NAME}} != "value with param" 7206b9b3e0SSimon J. Gerraty. error 7306b9b3e0SSimon J. Gerraty.endif 7406b9b3e0SSimon J. Gerraty.MAKEFLAGS: -d0 752c3632d1SSimon J. Gerraty 762c3632d1SSimon J. Gerratyall: 772c3632d1SSimon J. Gerraty @:; 78