1*2c3632d1SSimon J. Gerraty# $NetBSD: var-op-assign.mk,v 1.4 2020/08/25 16:20:32 rillig Exp $ 2*2c3632d1SSimon J. Gerraty# 3*2c3632d1SSimon J. Gerraty# Tests for the = variable assignment operator, which overwrites an existing 4*2c3632d1SSimon J. Gerraty# variable or creates it. 5*2c3632d1SSimon J. Gerraty 6*2c3632d1SSimon J. Gerraty# This is a simple variable assignment. 7*2c3632d1SSimon J. Gerraty# To the left of the assignment operator '=' there is the variable name, 8*2c3632d1SSimon J. Gerraty# and to the right is the variable value. 9*2c3632d1SSimon J. Gerraty# 10*2c3632d1SSimon J. GerratyVAR= value 11*2c3632d1SSimon J. Gerraty 12*2c3632d1SSimon J. Gerraty# This condition demonstrates that whitespace around the assignment operator 13*2c3632d1SSimon J. Gerraty# is discarded. Otherwise the value would start with a single tab. 14*2c3632d1SSimon J. Gerraty# 15*2c3632d1SSimon J. Gerraty.if ${VAR} != "value" 16*2c3632d1SSimon J. Gerraty.error 17*2c3632d1SSimon J. Gerraty.endif 18*2c3632d1SSimon J. Gerraty 19*2c3632d1SSimon J. Gerraty# Whitespace to the left of the assignment operator is ignored as well. 20*2c3632d1SSimon J. Gerraty# The variable value can contain arbitrary characters. 21*2c3632d1SSimon J. Gerraty# 22*2c3632d1SSimon J. Gerraty# The '#' needs to be escaped with a backslash, this happens in a very 23*2c3632d1SSimon J. Gerraty# early stage of parsing and applies to all line types, except for the 24*2c3632d1SSimon J. Gerraty# commands, which are indented with a tab. 25*2c3632d1SSimon J. Gerraty# 26*2c3632d1SSimon J. Gerraty# The '$' needs to be escaped with another '$', otherwise it would refer to 27*2c3632d1SSimon J. Gerraty# another variable. 28*2c3632d1SSimon J. Gerraty# 29*2c3632d1SSimon J. GerratyVAR =new value and \# some $$ special characters # comment 30*2c3632d1SSimon J. Gerraty 31*2c3632d1SSimon J. Gerraty# When a string literal appears in a condition, the escaping rules are 32*2c3632d1SSimon J. Gerraty# different. Run make with the -dc option to see the details. 33*2c3632d1SSimon J. Gerraty.if ${VAR} != "new value and \# some \$ special characters" 34*2c3632d1SSimon J. Gerraty.error ${VAR} 35*2c3632d1SSimon J. Gerraty.endif 36*2c3632d1SSimon J. Gerraty 37*2c3632d1SSimon J. Gerraty# The variable value may contain references to other variables. 38*2c3632d1SSimon J. Gerraty# In this example, the reference is to the variable with the empty name, 39*2c3632d1SSimon J. Gerraty# which always expands to an empty string. This alone would not produce 40*2c3632d1SSimon J. Gerraty# any side-effects, therefore the variable has a :!...! modifier that 41*2c3632d1SSimon J. Gerraty# executes a shell command. 42*2c3632d1SSimon J. GerratyVAR= ${:! echo 'not yet evaluated' 1>&2 !} 43*2c3632d1SSimon J. GerratyVAR= ${:! echo 'this will be evaluated later' 1>&2 !} 44*2c3632d1SSimon J. Gerraty 45*2c3632d1SSimon J. Gerraty# Now force the variable to be evaluated. 46*2c3632d1SSimon J. Gerraty# This outputs the line to stderr. 47*2c3632d1SSimon J. Gerraty.if ${VAR} 48*2c3632d1SSimon J. Gerraty.endif 49*2c3632d1SSimon J. Gerraty 50*2c3632d1SSimon J. Gerraty# In a variable assignment, the variable name must consist of a single word. 51*2c3632d1SSimon J. Gerraty# 52*2c3632d1SSimon J. GerratyVARIABLE NAME= variable value 53*2c3632d1SSimon J. Gerraty 54*2c3632d1SSimon J. Gerraty# But if the whitespace appears inside parentheses or braces, everything is 55*2c3632d1SSimon J. Gerraty# fine. 56*2c3632d1SSimon J. Gerraty# 57*2c3632d1SSimon J. Gerraty# XXX: This was not an intentional decision, as variable names typically 58*2c3632d1SSimon J. Gerraty# neither contain parentheses nor braces. This is only a side-effect from 59*2c3632d1SSimon J. Gerraty# the implementation of the parser, which cheats when parsing a variable 60*2c3632d1SSimon J. Gerraty# name. It only counts parentheses and braces instead of properly parsing 61*2c3632d1SSimon J. Gerraty# nested variable expressions such as VAR.${param}. 62*2c3632d1SSimon J. Gerraty# 63*2c3632d1SSimon J. GerratyVAR(spaces in parentheses)= () 64*2c3632d1SSimon J. GerratyVAR{spaces in braces}= {} 65*2c3632d1SSimon J. Gerraty 66*2c3632d1SSimon J. Gerraty# Be careful and use indirect variable names here, to prevent accidentally 67*2c3632d1SSimon J. Gerraty# accepting the test in case the parser just uses "VAR" as the variable name, 68*2c3632d1SSimon J. Gerraty# ignoring all the rest. 69*2c3632d1SSimon J. Gerraty# 70*2c3632d1SSimon J. GerratyVARNAME_PAREN= VAR(spaces in parentheses) 71*2c3632d1SSimon J. GerratyVARNAME_BRACES= VAR{spaces in braces} 72*2c3632d1SSimon J. Gerraty 73*2c3632d1SSimon J. Gerraty.if ${${VARNAME_PAREN}} != "()" 74*2c3632d1SSimon J. Gerraty.error 75*2c3632d1SSimon J. Gerraty.endif 76*2c3632d1SSimon J. Gerraty 77*2c3632d1SSimon J. Gerraty.if ${${VARNAME_BRACES}} != "{}" 78*2c3632d1SSimon J. Gerraty.error 79*2c3632d1SSimon J. Gerraty.endif 80*2c3632d1SSimon J. Gerraty 81*2c3632d1SSimon J. Gerraty# In safe mode, parsing would stop immediately after the "VARIABLE NAME=" 82*2c3632d1SSimon J. Gerraty# line, since any commands run after that are probably working with 83*2c3632d1SSimon J. Gerraty# unexpected variable values. 84*2c3632d1SSimon J. Gerraty# 85*2c3632d1SSimon J. Gerraty# Therefore, just output an info message. 86*2c3632d1SSimon J. Gerraty.info Parsing still continues until here. 87*2c3632d1SSimon J. Gerraty 88*2c3632d1SSimon J. Gerratyall: 89*2c3632d1SSimon J. Gerraty @:; 90