]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - unit-tests/var-op-assign.mk
Import bmake-20230622
[FreeBSD/FreeBSD.git] / unit-tests / var-op-assign.mk
1 # $NetBSD: var-op-assign.mk,v 1.9 2023/06/01 20:56:35 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 type
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 variable 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         @:;