]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bmake/unit-tests/var-op-expand.mk
zfs: merge openzfs/zfs@71c609852 (zfs-2.1-release) into stable/13
[FreeBSD/FreeBSD.git] / contrib / bmake / unit-tests / var-op-expand.mk
1 # $NetBSD: var-op-expand.mk,v 1.11 2021/01/01 23:07:48 sjg Exp $
2 #
3 # Tests for the := variable assignment operator, which expands its
4 # right-hand side.
5
6 .MAKE.SAVE_DOLLARS:=      yes
7
8 # If the right-hand side does not contain a dollar sign, the ':=' assignment
9 # operator has the same effect as the '=' assignment operator.
10 VAR:=                   value
11 .if ${VAR} != "value"
12 .  error
13 .endif
14
15 # When a ':=' assignment is performed, its right-hand side is evaluated and
16 # expanded as far as possible.  Contrary to other situations, '$$' and
17 # variable expressions based on undefined variables are preserved though.
18 #
19 # Whether a variable expression is undefined or not is determined at the end
20 # of evaluating the expression.  The consequence is that ${:Ufallback} expands
21 # to "fallback"; initially this expression is undefined since it is based on
22 # the variable named "", which is guaranteed to be never defined, but at the
23 # end of evaluating the expression ${:Ufallback}, the modifier ':U' has turned
24 # the expression into a defined expression.
25
26
27 # literal dollar signs
28 VAR:=           $$ $$$$ $$$$$$$$
29 .if ${VAR} != "\$ \$\$ \$\$\$\$"
30 .  error
31 .endif
32
33
34 # reference to a variable containing a literal dollar sign
35 REF=            $$ $$$$ $$$$$$$$
36 VAR:=           ${REF}
37 REF=            too late
38 .if ${VAR} != "\$ \$\$ \$\$\$\$"
39 .  error
40 .endif
41
42
43 # reference to an undefined variable
44 .undef UNDEF
45 VAR:=           <${UNDEF}>
46 UNDEF=          after
47 .if ${VAR} != "<after>"
48 .  error
49 .endif
50
51
52 # reference to a variable whose name is computed from another variable
53 REF2=           referred to
54 REF=            REF2
55 VAR:=           ${${REF}}
56 REF=            too late
57 .if ${VAR} != "referred to"
58 .  error
59 .endif
60
61
62 # expression with an indirect modifier referring to an undefined variable
63 .undef UNDEF
64 VAR:=           ${:${UNDEF}}
65 UNDEF=          Uwas undefined
66 .if ${VAR} != "was undefined"
67 .  error
68 .endif
69
70
71 # expression with an indirect modifier referring to another variable that
72 # in turn refers to an undefined variable
73 #
74 # XXX: Even though this is a ':=' assignment, the '${UNDEF}' in the part of
75 # the variable modifier is not preserved.  To preserve it, ParseModifierPart
76 # would have to call VarSubstExpr somehow since this is the only piece of
77 # code that takes care of this global variable.
78 .undef UNDEF
79 REF=            U${UNDEF}
80 #.MAKEFLAGS: -dv
81 VAR:=           ${:${REF}}
82 #.MAKEFLAGS: -d0
83 REF=            too late
84 UNDEF=          Uwas undefined
85 .if ${VAR} != ""
86 .  error
87 .endif
88
89
90 # In variable assignments using the ':=' operator, undefined variables are
91 # preserved, no matter how indirectly they are referenced.
92 .undef REF3
93 REF2=           <${REF3}>
94 REF=            ${REF2}
95 VAR:=           ${REF}
96 REF3=           too late
97 .if ${VAR} != "<too late>"
98 .  error
99 .endif
100
101
102 # In variable assignments using the ':=' operator, '$$' are preserved, no
103 # matter how indirectly they are referenced.
104 REF2=           REF2:$$ $$$$
105 REF=            REF:$$ $$$$ ${REF2}
106 VAR:=           VAR:$$ $$$$ ${REF}
107 .if ${VAR} != "VAR:\$ \$\$ REF:\$ \$\$ REF2:\$ \$\$"
108 .  error
109 .endif
110
111
112 # In variable assignments using the ':=' operator, '$$' are preserved in the
113 # expressions of the top level, but not in expressions that are nested.
114 VAR:=           top:$$ ${:Unest1\:\$\$} ${:Unest2${:U\:\$\$}}
115 .if ${VAR} != "top:\$ nest1:\$ nest2:\$"
116 .  error
117 .endif
118
119
120 # In variable assignments using the ':=' operator, there may be expressions
121 # containing variable modifiers, and these modifiers may refer to other
122 # variables.  These referred-to variables are expanded at the time of
123 # assignment.  The undefined variables are kept as-is and are later expanded
124 # when evaluating the condition.
125 #
126 # Contrary to the assignment operator '=', the assignment operator ':='
127 # consumes the '$' from modifier parts.
128 REF.word=       1:$$ 2:$$$$ 4:$$$$$$$$
129 .undef REF.undef
130 VAR:=           ${:Uword undef:@word@${REF.${word}}@}, direct: ${REF.word} ${REF.undef}
131 REF.word=       word.after
132 REF.undef=      undef.after
133 .if ${VAR} != "1:2:\$ 4:\$\$ undef.after, direct: 1:\$ 2:\$\$ 4:\$\$\$\$ undef.after"
134 .  error
135 .endif
136
137 # Just for comparison, the previous example using the assignment operator '='
138 # instead of ':='.  The right-hand side of the assignment is not evaluated at
139 # the time of assignment but only later, when ${VAR} appears in the condition.
140 #
141 # At that point, both REF.word and REF.undef are defined.
142 REF.word=       1:$$ 2:$$$$ 4:$$$$$$$$
143 .undef REF.undef
144 VAR=            ${:Uword undef:@word@${REF.${word}}@}, direct: ${REF.word} ${REF.undef}
145 REF.word=       word.after
146 REF.undef=      undef.after
147 .if ${VAR} != "word.after undef.after, direct: word.after undef.after"
148 .  error
149 .endif
150
151
152 # Between var.c 1.42 from 2000-05-11 and before parse.c 1.520 from 2020-12-27,
153 # if the variable name in a ':=' assignment referred to an undefined variable,
154 # there were actually 2 assignments to different variables:
155 #
156 #       Global["VAR_SUBST_${UNDEF}"] = ""
157 #       Global["VAR_SUBST_"] = ""
158 #
159 # The variable name with the empty value actually included a dollar sign.
160 # Variable names with dollars are not used in practice.
161 #
162 # It might be a good idea to forbid undefined variables on the left-hand side
163 # of a variable assignment.
164 .undef UNDEF
165 VAR_ASSIGN_${UNDEF}=    assigned by '='
166 VAR_SUBST_${UNDEF}:=    assigned by ':='
167 .if ${VAR_ASSIGN_} != "assigned by '='"
168 .  error
169 .endif
170 .if defined(${:UVAR_SUBST_\${UNDEF\}})
171 .  error
172 .endif
173 .if ${VAR_SUBST_} != "assigned by ':='"
174 .  error
175 .endif
176
177 all:
178         @:;