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