xref: /freebsd/contrib/bmake/unit-tests/cond-token-plain.mk (revision 6ba2210ee039f2f12878c217bcf058e9c8b26b29)
1# $NetBSD: cond-token-plain.mk,v 1.10 2021/01/21 14:08:09 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
105VAR=	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# FIXME: In CondParser_String, Var_Parse returns var_Error without a
181# corresponding error message.
182.if $$$$$$$$ != ""
183.  error
184.else
185.  error
186.endif
187
188# See cond-token-string.mk for similar tests where the condition is enclosed
189# in "quotes".
190
191all:
192	@:;
193