1*d5e0a182SSimon J. Gerraty# $NetBSD: var-op-assign.mk,v 1.11 2023/11/19 21:47:52 rillig Exp $ 22c3632d1SSimon J. Gerraty# 32c3632d1SSimon J. Gerraty# Tests for the = variable assignment operator, which overwrites an existing 42c3632d1SSimon J. Gerraty# variable or creates it. 52c3632d1SSimon J. Gerraty 62c3632d1SSimon J. Gerraty# This is a simple variable assignment. 72c3632d1SSimon J. Gerraty# To the left of the assignment operator '=' there is the variable name, 8e2eeea75SSimon J. Gerraty# and to the right is the variable value. The variable value is stored as-is, 9e2eeea75SSimon J. Gerraty# it is not expanded in any way. 102c3632d1SSimon J. Gerraty# 112c3632d1SSimon J. GerratyVAR= value 122c3632d1SSimon J. Gerraty 132c3632d1SSimon J. Gerraty# This condition demonstrates that whitespace around the assignment operator 142c3632d1SSimon J. Gerraty# is discarded. Otherwise the value would start with a single tab. 152c3632d1SSimon J. Gerraty# 162c3632d1SSimon J. Gerraty.if ${VAR} != "value" 172c3632d1SSimon J. Gerraty. error 182c3632d1SSimon J. Gerraty.endif 192c3632d1SSimon J. Gerraty 202c3632d1SSimon J. Gerraty# Whitespace to the left of the assignment operator is ignored as well. 212c3632d1SSimon J. Gerraty# The variable value can contain arbitrary characters. 222c3632d1SSimon J. Gerraty# 232c3632d1SSimon J. Gerraty# The '#' needs to be escaped with a backslash, this happens in a very 242c3632d1SSimon J. Gerraty# early stage of parsing and applies to all line types, except for the 252c3632d1SSimon J. Gerraty# commands, which are indented with a tab. 262c3632d1SSimon J. Gerraty# 272c3632d1SSimon J. Gerraty# The '$' needs to be escaped with another '$', otherwise it would refer to 282c3632d1SSimon J. Gerraty# another variable. 292c3632d1SSimon J. Gerraty# 302c3632d1SSimon J. GerratyVAR= new value and \# some $$ special characters # comment 312c3632d1SSimon J. Gerraty 322c3632d1SSimon J. Gerraty# When a string literal appears in a condition, the escaping rules are 332c3632d1SSimon J. Gerraty# different. Run make with the -dc option to see the details. 342c3632d1SSimon J. Gerraty.if ${VAR} != "new value and \# some \$ special characters" 352c3632d1SSimon J. Gerraty. error ${VAR} 362c3632d1SSimon J. Gerraty.endif 372c3632d1SSimon J. Gerraty 382c3632d1SSimon J. Gerraty# The variable value may contain references to other variables. 392c3632d1SSimon J. Gerraty# In this example, the reference is to the variable with the empty name, 40e2eeea75SSimon J. Gerraty# which is never defined. 41e2eeea75SSimon J. Gerraty# 42e2eeea75SSimon J. Gerraty# This alone would not produce any side-effects, therefore the variable has 43e2eeea75SSimon J. Gerraty# a :!...! modifier that executes a shell command. The :!...! modifier turns 44e2eeea75SSimon J. Gerraty# an undefined expression into a defined one, see ApplyModifier_ShellCommand, 45b0c40a00SSimon J. Gerraty# the call to Expr_Define. 46e2eeea75SSimon J. Gerraty# 47e2eeea75SSimon J. Gerraty# Since the right-hand side of a '=' assignment is not expanded at the time 48e2eeea75SSimon J. Gerraty# when the variable is defined, the first command is not run at all. 492c3632d1SSimon J. GerratyVAR= ${:! echo 'not yet evaluated' 1>&2 !} 502c3632d1SSimon J. GerratyVAR= ${:! echo 'this will be evaluated later' 1>&2 !} 512c3632d1SSimon J. Gerraty 522c3632d1SSimon J. Gerraty# Now force the variable to be evaluated. 532c3632d1SSimon J. Gerraty# This outputs the line to stderr. 542c3632d1SSimon J. Gerraty.if ${VAR} 552c3632d1SSimon J. Gerraty.endif 562c3632d1SSimon J. Gerraty 572c3632d1SSimon J. Gerraty# In a variable assignment, the variable name must consist of a single word. 58e2eeea75SSimon J. Gerraty# The following line therefore generates a parse error. 5998875883SSimon J. Gerraty# expect+1: Invalid line 'VARIABLE NAME= variable value' 602c3632d1SSimon J. GerratyVARIABLE NAME= variable value 612c3632d1SSimon J. Gerraty 622c3632d1SSimon J. Gerraty# But if the whitespace appears inside parentheses or braces, everything is 632c3632d1SSimon J. Gerraty# fine. 642c3632d1SSimon J. Gerraty# 652c3632d1SSimon J. Gerraty# XXX: This was not an intentional decision, as variable names typically 662c3632d1SSimon J. Gerraty# neither contain parentheses nor braces. This is only a side-effect from 672c3632d1SSimon J. Gerraty# the implementation of the parser, which cheats when parsing a variable 682c3632d1SSimon J. Gerraty# name. It only counts parentheses and braces instead of properly parsing 69*d5e0a182SSimon J. Gerraty# nested expressions such as VAR.${param}. 702c3632d1SSimon J. Gerraty# 712c3632d1SSimon J. GerratyVAR(spaces in parentheses)= () 722c3632d1SSimon J. GerratyVAR{spaces in braces}= {} 732c3632d1SSimon J. Gerraty 742c3632d1SSimon J. Gerraty# Be careful and use indirect variable names here, to prevent accidentally 752c3632d1SSimon J. Gerraty# accepting the test in case the parser just uses "VAR" as the variable name, 762c3632d1SSimon J. Gerraty# ignoring all the rest. 772c3632d1SSimon J. Gerraty# 782c3632d1SSimon J. GerratyVARNAME_PAREN= VAR(spaces in parentheses) 792c3632d1SSimon J. GerratyVARNAME_BRACES= VAR{spaces in braces} 802c3632d1SSimon J. Gerraty 812c3632d1SSimon J. Gerraty.if ${${VARNAME_PAREN}} != "()" 822c3632d1SSimon J. Gerraty. error 832c3632d1SSimon J. Gerraty.endif 842c3632d1SSimon J. Gerraty 852c3632d1SSimon J. Gerraty.if ${${VARNAME_BRACES}} != "{}" 862c3632d1SSimon J. Gerraty. error 872c3632d1SSimon J. Gerraty.endif 882c3632d1SSimon J. Gerraty 892c3632d1SSimon J. Gerraty# In safe mode, parsing would stop immediately after the "VARIABLE NAME=" 902c3632d1SSimon J. Gerraty# line, since any commands run after that are probably working with 912c3632d1SSimon J. Gerraty# unexpected variable values. 922c3632d1SSimon J. Gerraty# 932c3632d1SSimon J. Gerraty# Therefore, just output an info message. 94148ee845SSimon J. Gerraty# expect+1: Parsing still continues until here. 952c3632d1SSimon J. Gerraty.info Parsing still continues until here. 962c3632d1SSimon J. Gerraty 972c3632d1SSimon J. Gerratyall: 982c3632d1SSimon J. Gerraty @:; 99