cond-token-plain.mk revision 1.9 1 # $NetBSD: cond-token-plain.mk,v 1.9 2021/01/21 13:52:32 rillig Exp $
2 #
3 # Tests for plain tokens (that is, string literals without quotes)
4 # in .if conditions.
5
6 .MAKEFLAGS: -dc
7
8 .if ${:Uvalue} != value
9 . error
10 .endif
11
12 # Malformed condition since comment parsing is done in an early phase
13 # and removes the '#' and everything behind it long before the condition
14 # parser gets to see it.
15 #
16 # XXX: The error message is missing for this malformed condition.
17 # The right-hand side of the comparison is just a '"', before unescaping.
18 .if ${:U} != "#hash"
19 . error
20 .endif
21
22 # To get a '#' into a condition, it has to be escaped using a backslash.
23 # This prevents the comment parser from removing it, and in turn, it becomes
24 # visible to CondParser_String.
25 .if ${:U\#hash} != "\#hash"
26 . error
27 .endif
28
29 # Since 2002-12-30, and still as of 2020-09-11, CondParser_Token handles
30 # the '#' specially, even though at this point, there should be no need for
31 # comment handling anymore. The comments are supposed to be stripped off
32 # in a very early parsing phase.
33 #
34 # See https://gnats.netbsd.org/19596 for example makefiles demonstrating the
35 # original problems. This workaround is probably not needed anymore.
36 #
37 # XXX: Missing error message for the malformed condition. The right-hand
38 # side before unescaping is double-quotes, backslash, backslash.
39 .if ${:U\\} != "\\#hash"
40 . error
41 .endif
42
43 # The right-hand side of a comparison is not parsed as a token, therefore
44 # the code from CondParser_Token does not apply to it.
45 # TODO: Explain the consequences.
46 # TODO: Does this mean that more syntactic variants are allowed here?
47 .if ${:U\#hash} != \#hash
48 . error
49 .endif
50
51 # XXX: What is the purpose of treating an escaped '#' in the following
52 # condition as a comment? And why only at the beginning of a token,
53 # just as in the shell?
54 .if 0 \# This is treated as a comment, but why?
55 . error
56 .endif
57
58 # Ah, ok, this can be used to add an end-of-condition comment. But does
59 # anybody really use this? This is neither documented nor obvious since
60 # the '#' is escaped. It's much clearer to write a comment in the line
61 # above the condition.
62 .if ${0 \# comment :?yes:no} != no
63 . error
64 .endif
65 .if ${1 \# comment :?yes:no} != yes
66 . error
67 .endif
68
69 # Usually there is whitespace around the comparison operator, but this is
70 # not required.
71 .if ${UNDEF:Uundefined}!=undefined
72 . error
73 .endif
74 .if ${UNDEF:U12345}>12345
75 . error
76 .endif
77 .if ${UNDEF:U12345}<12345
78 . error
79 .endif
80 .if (${UNDEF:U0})||0
81 . error
82 .endif
83
84 # Only the comparison operator terminates the comparison operand, and it's
85 # a coincidence that the '!' is both used in the '!=' comparison operator
86 # as well as for negating a comparison result.
87 #
88 # The boolean operators '&' and '|' don't terminate a comparison operand.
89 .if ${:Uvar}&&name != "var&&name"
90 . error
91 .endif
92 .if ${:Uvar}||name != "var||name"
93 . error
94 .endif
95
96 # A bare word may appear alone in a condition, without any comparison
97 # operator. It is implicitly converted into defined(bare).
98 .if bare
99 . error
100 .else
101 . info A bare word is treated like defined(...), and the variable $\
102 'bare' is not defined.
103 .endif
104
105 VAR= defined
106 .if VAR
107 . info A bare word is treated like defined(...).
108 .else
109 . error
110 .endif
111
112 # Bare words may be intermixed with variable expressions.
113 .if V${:UA}R
114 . info ok
115 .else
116 . error
117 .endif
118
119 # In bare words, even undefined variables are allowed. Without the bare
120 # words, undefined variables are not allowed. That feels inconsistent.
121 .if V${UNDEF}AR
122 . info Undefined variables in bare words expand to an empty string.
123 .else
124 . error
125 .endif
126
127 .if 0${:Ux00}
128 . error
129 .else
130 . info Numbers can be composed from literals and variable expressions.
131 .endif
132
133 .if 0${:Ux01}
134 . info Numbers can be composed from literals and variable expressions.
135 .else
136 . error
137 .endif
138
139 # If the right-hand side is missing, it's a parse error.
140 .if "" ==
141 . error
142 .else
143 . error
144 .endif
145
146 # If the left-hand side is missing, it's a parse error as well, but without
147 # a specific error message.
148 .if == ""
149 . error
150 .else
151 . error
152 .endif
153
154 # The '\\' is not a line continuation. Neither is it an unquoted string
155 # literal. Instead, it is parsed as a function argument (ParseFuncArg),
156 # and in that context, the backslash is just an ordinary character. The
157 # function argument thus stays '\\' (2 backslashes). This string is passed
158 # to FuncDefined, and since there is no variable named '\\', the condition
159 # evaluates to false.
160 .if \\
161 . error
162 .else
163 . info The variable '\\' is not defined.
164 .endif
165
166 ${:U\\\\}= backslash
167 .if \\
168 . info Now the variable '\\' is defined.
169 .else
170 . error
171 .endif
172
173 # Anything that doesn't start with a double quote is considered a "bare word".
174 # Strangely, a bare word may contain double quotes inside. Nobody should ever
175 # depend on this since it may well be unintended. See CondParser_String.
176 .if "unquoted\"quoted" != unquoted"quoted
177 . error
178 .endif
179
180 # See cond-token-string.mk for similar tests where the condition is enclosed
181 # in "quotes".
182
183 all:
184 @:;
185