cond-func-empty.mk revision 1.7 1 1.7 rillig # $NetBSD: cond-func-empty.mk,v 1.7 2020/09/23 07:50:58 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.3 rillig # optionally followed by variable modifiers. This is like the defined()
8 1.3 rillig # function.
9 1.3 rillig #
10 1.3 rillig
11 1.3 rillig .undef UNDEF
12 1.3 rillig EMPTY= # empty
13 1.3 rillig SPACE= ${:U }
14 1.3 rillig WORD= word
15 1.3 rillig
16 1.3 rillig # An undefined variable is empty.
17 1.3 rillig .if !empty(UNDEF)
18 1.3 rillig . error
19 1.3 rillig .endif
20 1.3 rillig
21 1.3 rillig # An undefined variable has the empty string as the value, and the :M
22 1.3 rillig # variable modifier does not change that.
23 1.3 rillig #
24 1.3 rillig .if !empty(UNDEF:M*)
25 1.3 rillig . error
26 1.3 rillig .endif
27 1.3 rillig
28 1.3 rillig # The :S modifier replaces the empty value with an actual word, and
29 1.3 rillig # after that the expression is no longer empty. Because the variable
30 1.3 rillig # was undefined in the first place, the expression has the flag VAR_JUNK
31 1.3 rillig # but not VAR_KEEP, therefore it is still considered undefined.
32 1.4 rillig # Only very few variable modifiers turn an undefined variable expression
33 1.4 rillig # into a defined variable expression. The :U and :D modifiers belong to
34 1.4 rillig # that group, but :S doesn't (see VAR_KEEP).
35 1.3 rillig #
36 1.3 rillig # XXX: This is hard to explain to someone who doesn't know these
37 1.3 rillig # implementation details.
38 1.3 rillig #
39 1.3 rillig .if !empty(UNDEF:S,^$,value,W)
40 1.3 rillig . error
41 1.3 rillig .endif
42 1.3 rillig
43 1.3 rillig # The :U modifier modifies expressions based on undefined variables
44 1.3 rillig # (VAR_JUNK) by adding the VAR_KEEP flag, which marks the expression
45 1.3 rillig # as "being interesting enough to be further processed".
46 1.3 rillig #
47 1.3 rillig .if empty(UNDEF:S,^$,value,W:Ufallback)
48 1.3 rillig . error
49 1.3 rillig .endif
50 1.3 rillig
51 1.3 rillig # And now to the surprising part. Applying the following :S modifier to the
52 1.3 rillig # undefined variable makes it non-empty, but the marker VAR_JUNK is preserved
53 1.3 rillig # nevertheless. The :U modifier that follows only looks at VAR_JUNK to decide
54 1.3 rillig # whether the variable is defined or not. This kind of makes sense since the
55 1.3 rillig # :U modifier tests the _variable_, not the _expression_.
56 1.3 rillig #
57 1.3 rillig # But since the variable was undefined to begin with, the fallback value is
58 1.3 rillig # used in this expression.
59 1.3 rillig #
60 1.3 rillig .if ${UNDEF:S,^$,value,W:Ufallback} != "fallback"
61 1.3 rillig . error
62 1.3 rillig .endif
63 1.3 rillig
64 1.3 rillig # The variable EMPTY is completely empty (0 characters).
65 1.3 rillig .if !empty(EMPTY)
66 1.3 rillig . error
67 1.3 rillig .endif
68 1.3 rillig
69 1.3 rillig # The variable SPACE has a single space, which counts as being empty.
70 1.3 rillig .if !empty(SPACE)
71 1.3 rillig . error
72 1.3 rillig .endif
73 1.3 rillig
74 1.3 rillig # The variable .newline has a single newline, which counts as being empty.
75 1.3 rillig .if !empty(.newline)
76 1.3 rillig . error
77 1.3 rillig .endif
78 1.3 rillig
79 1.3 rillig # The empty variable named "" gets a fallback value of " ", which counts as
80 1.3 rillig # empty.
81 1.3 rillig #
82 1.3 rillig # Contrary to the other functions in conditionals, the trailing space is not
83 1.3 rillig # stripped off, as can be seen in the -dv debug log. If the space had been
84 1.3 rillig # stripped, it wouldn't make a difference in this case.
85 1.3 rillig #
86 1.3 rillig .if !empty(:U )
87 1.3 rillig . error
88 1.3 rillig .endif
89 1.3 rillig
90 1.3 rillig # Now the variable named " " gets a non-empty value, which demonstrates that
91 1.3 rillig # neither leading nor trailing spaces are trimmed in the argument of the
92 1.3 rillig # function. If the spaces were trimmed, the variable name would be "" and
93 1.6 rillig # that variable is indeed undefined. Since ParseEmptyArg calls Var_Parse
94 1.3 rillig # without VARE_UNDEFERR, the value of the undefined variable is returned as
95 1.3 rillig # an empty string.
96 1.3 rillig ${:U }= space
97 1.3 rillig .if empty( )
98 1.3 rillig . error
99 1.3 rillig .endif
100 1.3 rillig
101 1.3 rillig # The value of the following expression is " word", which is not empty.
102 1.3 rillig .if empty(:U word)
103 1.3 rillig . error
104 1.3 rillig .endif
105 1.3 rillig
106 1.3 rillig # The :L modifier creates a variable expression that has the same value as
107 1.3 rillig # its name, which both are "VAR" in this case. The value is therefore not
108 1.3 rillig # empty.
109 1.3 rillig .if empty(VAR:L)
110 1.3 rillig . error
111 1.3 rillig .endif
112 1.3 rillig
113 1.3 rillig # The variable WORD has the value "word", which does not count as empty.
114 1.3 rillig .if empty(WORD)
115 1.3 rillig . error
116 1.3 rillig .endif
117 1.1 rillig
118 1.3 rillig # The expression ${} for a variable with the empty name always evaluates
119 1.7 rillig # to an empty string (see Var_Parse, varUndefined).
120 1.3 rillig .if !empty()
121 1.3 rillig . error
122 1.3 rillig .endif
123 1.1 rillig
124 1.5 rillig # Ensure that variable expressions that appear as part of the argument are
125 1.5 rillig # properly parsed. Typical use cases for this are .for loops, which are
126 1.5 rillig # expanded to exactly these ${:U} expressions.
127 1.5 rillig #
128 1.5 rillig # If everything goes well, the argument expands to "WORD", and that variable
129 1.5 rillig # is defined at the beginning of this file. The surrounding 'W' and 'D'
130 1.5 rillig # ensure that the parser in ParseEmptyArg has the correct position, both
131 1.5 rillig # before and after the call to Var_ParsePP.
132 1.5 rillig .if empty(W${:UOR}D)
133 1.5 rillig . error
134 1.5 rillig .endif
135 1.5 rillig
136 1.1 rillig all:
137 1.1 rillig @:;
138