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