cond-func-empty.mk revision 1.17 1 # $NetBSD: cond-func-empty.mk,v 1.17 2021/12/28 22:13:56 rillig Exp $
2 #
3 # Tests for the empty() function in .if conditions, which tests a variable
4 # expression for emptiness.
5 #
6 # Note that the argument in the parentheses is a variable name, not a variable
7 # expression, optionally followed by variable modifiers.
8 #
9
10 .undef UNDEF
11 EMPTY= # empty
12 SPACE= ${:U }
13 WORD= word
14
15 # An undefined variable is empty.
16 .if !empty(UNDEF)
17 . error
18 .endif
19
20 # An undefined variable has the empty string as the value, and the :M
21 # variable modifier does not change that.
22 #
23 .if !empty(UNDEF:M*)
24 . error
25 .endif
26
27 # The :S modifier replaces the empty value with an actual word. The
28 # expression is now no longer empty, but it is still based on an undefined
29 # variable (DEF_UNDEF). There are a few variable modifiers that turn an
30 # undefined expression into a defined expression, among them :U and :D, but
31 # not :S.
32 #
33 # XXX: This is hard to explain to someone who doesn't know these
34 # implementation details.
35 #
36 .if !empty(UNDEF:S,^$,value,W)
37 . error
38 .endif
39
40 # The :U modifier changes the state of a previously undefined expression from
41 # DEF_UNDEF to DEF_DEFINED. This marks the expression as "being interesting
42 # enough to be further processed".
43 #
44 .if empty(UNDEF:S,^$,value,W:Ufallback)
45 . error
46 .endif
47
48 # And now to the surprising part. Applying the following :S modifier to the
49 # undefined expression makes it non-empty, but the expression is still in
50 # state DEF_UNDEF. The :U modifier that follows only looks at the state
51 # DEF_UNDEF to decide whether the variable is defined or not. This kind of
52 # makes sense since the :U modifier tests the _variable_, not the
53 # _expression_.
54 #
55 # But since the variable was undefined to begin with, the fallback value from
56 # the :U modifier is used in this expression.
57 #
58 .if ${UNDEF:S,^$,value,W:Ufallback} != "fallback"
59 . error
60 .endif
61
62 # The variable EMPTY is completely empty (0 characters).
63 .if !empty(EMPTY)
64 . error
65 .endif
66
67 # The variable SPACE has a single space, which counts as being empty.
68 .if !empty(SPACE)
69 . error
70 .endif
71
72 # The variable .newline has a single newline, which counts as being empty.
73 .if !empty(.newline)
74 . error
75 .endif
76
77 # The following example constructs an expression with the variable name ""
78 # and the value " ". This expression counts as empty since the value contains
79 # only whitespace.
80 #
81 # Contrary to the other functions in conditionals, the trailing space is not
82 # stripped off, as can be seen in the -dv debug log. If the space had been
83 # stripped, it wouldn't make a difference in this case, but in other cases.
84 #
85 .if !empty(:U )
86 . error
87 .endif
88
89 # Now the variable named " " gets a non-empty value, which demonstrates that
90 # neither leading nor trailing spaces are trimmed in the argument of the
91 # function. If the spaces were trimmed, the variable name would be "" and
92 # that variable is indeed undefined. Since CondParser_FuncCallEmpty calls
93 # Var_Parse without VARE_UNDEFERR, the value of the undefined variable is
94 # returned as an empty string.
95 ${:U }= space
96 .if empty( )
97 . error
98 .endif
99
100 # The value of the following expression is " word", which is not empty.
101 .if empty(:U word)
102 . error
103 .endif
104
105 # The :L modifier creates a variable expression that has the same value as
106 # its name, which both are "VAR" in this case. The value is therefore not
107 # empty.
108 .if empty(VAR:L)
109 . error
110 .endif
111
112 # The variable WORD has the value "word", which does not count as empty.
113 .if empty(WORD)
114 . error
115 .endif
116
117 # The expression ${} for a variable with the empty name always evaluates
118 # to an empty string (see Var_Parse, varUndefined).
119 .if !empty()
120 . error
121 .endif
122
123 # Ensure that variable expressions that appear as part of the argument are
124 # properly parsed. Typical use cases for this are .for loops, which are
125 # expanded to exactly these ${:U} expressions.
126 #
127 # If everything goes well, the argument expands to "WORD", and that variable
128 # is defined at the beginning of this file. The surrounding 'W' and 'D'
129 # ensure that CondParser_FuncCallEmpty keeps track of the parsing position,
130 # both before and after the call to Var_Parse.
131 .if empty(W${:UOR}D)
132 . error
133 .endif
134
135 # There may be spaces at the outside of the parentheses.
136 # Spaces inside the parentheses are interpreted as part of the variable name.
137 .if ! empty ( WORD )
138 . error
139 .endif
140
141 ${:U WORD }= variable name with spaces
142
143 # Now there is a variable named " WORD ", and it is not empty.
144 .if empty ( WORD )
145 . error
146 .endif
147
148 # Parse error: missing closing parenthesis.
149 .if empty(WORD
150 . error
151 .else
152 . error
153 .endif
154
155 # Since cond.c 1.76 from 2020-06-28 and before var.c 1.226 from 2020-07-02,
156 # the following example generated a wrong error message "Variable VARNAME is
157 # recursive".
158 #
159 # Since at least 1993, the manual page claimed that irrelevant parts of
160 # conditions were not evaluated, but that was wrong for a long time. The
161 # expressions in irrelevant parts of the condition were actually evaluated,
162 # they just allowed undefined variables to be used in the conditions, and the
163 # result of evaluating them was not used further. These unnecessary
164 # evaluations were fixed in several commits, starting with var.c 1.226 from
165 # 2020-07-02.
166 #
167 # In this example, the variable "VARNAME2" is not defined, so evaluation of
168 # the condition should have stopped at this point, and the rest of the
169 # condition should have been processed in parse-only mode. The right-hand
170 # side containing the '!empty' was evaluated though, as it had always been.
171 #
172 # When evaluating the !empty condition, the variable name was parsed as
173 # "VARNAME${:U2}", but without expanding any nested variable expression, in
174 # this case the ${:U2}. The expression '${:U2}' was replaced with an empty
175 # string, the resulting variable name was thus "VARNAME". This conceptually
176 # wrong variable name should have been discarded quickly after parsing it, to
177 # prevent it from doing any harm.
178 #
179 # The variable expression was expanded though, and this was wrong. The
180 # expansion was done without VARE_WANTRES (called VARF_WANTRES back
181 # then) though. This had the effect that the ${:U1} from the value of VARNAME
182 # expanded to an empty string. This in turn created the seemingly recursive
183 # definition VARNAME=${VARNAME}, and that definition was never meant to be
184 # expanded.
185 #
186 # This was fixed by expanding nested variable expressions in the variable name
187 # only if the flag VARE_WANTRES is given.
188 VARNAME= ${VARNAME${:U1}}
189 .if defined(VARNAME${:U2}) && !empty(VARNAME${:U2})
190 .endif
191
192
193 # If the word 'empty' is not followed by '(', it is not a function call but an
194 # ordinary bare word. This bare word is interpreted as 'defined(empty)', and
195 # since there is no variable named 'empty', the condition evaluates to false.
196 .if empty
197 . error
198 .endif
199
200 empty= # defined but empty
201 .if empty
202 .else
203 . error
204 .endif
205