1 # $NetBSD: var-op-assign.mk,v 1.12 2025/06/28 22:39:29 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 # 11 VAR= 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 # 30 VAR= 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. 49 VAR= ${:! echo 'not yet evaluated' 1>&2 !} 50 VAR= ${:! 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" 60 VARIABLE 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 # 71 VAR(spaces in parentheses)= () 72 VAR{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 # 78 VARNAME_PAREN= VAR(spaces in parentheses) 79 VARNAME_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 97 all: 98 @:; 99