xref: /freebsd/contrib/bmake/unit-tests/directive-include-guard.mk (revision d5e0a182cf153f8993a633b93d9220c99a89e760)
1*d5e0a182SSimon J. Gerraty# $NetBSD: directive-include-guard.mk,v 1.16 2023/12/17 14:07:22 rillig Exp $
2148ee845SSimon J. Gerraty#
3148ee845SSimon J. Gerraty# Tests for multiple-inclusion guards in makefiles.
4148ee845SSimon J. Gerraty#
5148ee845SSimon J. Gerraty# A file that is guarded by a multiple-inclusion guard has one of the
6148ee845SSimon J. Gerraty# following forms:
7148ee845SSimon J. Gerraty#
8148ee845SSimon J. Gerraty#	.ifndef GUARD_VARIABLE
9148ee845SSimon J. Gerraty#	.endif
10148ee845SSimon J. Gerraty#
11148ee845SSimon J. Gerraty#	.if !defined(GUARD_VARIABLE)
12148ee845SSimon J. Gerraty#	.endif
13148ee845SSimon J. Gerraty#
14148ee845SSimon J. Gerraty#	.if !target(guard-target)
15148ee845SSimon J. Gerraty#	.endif
16148ee845SSimon J. Gerraty#
17148ee845SSimon J. Gerraty# When such a file is included for the second or later time, and the guard
18*d5e0a182SSimon J. Gerraty# variable or the guard target is defined, the file is skipped completely, as
19*d5e0a182SSimon J. Gerraty# including it would not have any effect, not even on the special variable
20*d5e0a182SSimon J. Gerraty# '.MAKE.MAKEFILES', as that variable skips duplicate pathnames.
21148ee845SSimon J. Gerraty#
22148ee845SSimon J. Gerraty# See also:
23148ee845SSimon J. Gerraty#	https://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
24148ee845SSimon J. Gerraty
25148ee845SSimon J. Gerraty# Each of the following test cases creates a temporary file named after the
26148ee845SSimon J. Gerraty# test case and writes some lines of text to that file.  That file is then
27148ee845SSimon J. Gerraty# included twice, to see whether the second '.include' is skipped.
28148ee845SSimon J. Gerraty
29148ee845SSimon J. Gerraty
30148ee845SSimon J. Gerraty# This is the canonical form of a variable-based multiple-inclusion guard.
31*d5e0a182SSimon J. GerratyCASES+=	variable-ifndef
32148ee845SSimon J. GerratyLINES.variable-ifndef= \
33148ee845SSimon J. Gerraty	'.ifndef VARIABLE_IFNDEF' \
34148ee845SSimon J. Gerraty	'VARIABLE_IFNDEF=' \
35148ee845SSimon J. Gerraty	'.endif'
36148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef.tmp, line 1
37148ee845SSimon J. Gerraty# expect: Skipping 'variable-ifndef.tmp' because 'VARIABLE_IFNDEF' is defined
38148ee845SSimon J. Gerraty
39148ee845SSimon J. Gerraty# A file that reuses a guard from a previous file (or whose guard is defined
40148ee845SSimon J. Gerraty# for any other reason) is only processed once, to see whether it is guarded.
41148ee845SSimon J. Gerraty# Its content is skipped, therefore the syntax error is not detected.
42*d5e0a182SSimon J. GerratyCASES+=	variable-ifndef-reuse
43148ee845SSimon J. GerratyLINES.variable-ifndef-reuse= \
44148ee845SSimon J. Gerraty	'.ifndef VARIABLE_IFNDEF' \
45148ee845SSimon J. Gerraty	'syntax error' \
46148ee845SSimon J. Gerraty	'.endif'
47148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-reuse.tmp, line 1
48148ee845SSimon J. Gerraty# expect: Skipping 'variable-ifndef-reuse.tmp' because 'VARIABLE_IFNDEF' is defined
49148ee845SSimon J. Gerraty
50*d5e0a182SSimon J. Gerraty# The guard variable cannot be a number, as numbers are interpreted
51*d5e0a182SSimon J. Gerraty# differently from bare words.
52*d5e0a182SSimon J. GerratyCASES+=	variable-ifndef-zero
53*d5e0a182SSimon J. GerratyLINES.variable-ifndef-zero= \
54*d5e0a182SSimon J. Gerraty	'.ifndef 0e0' \
55*d5e0a182SSimon J. Gerraty	'syntax error' \
56*d5e0a182SSimon J. Gerraty	'.endif'
57*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-zero.tmp, line 1
58*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-zero.tmp, line 1
59*d5e0a182SSimon J. Gerraty
60*d5e0a182SSimon J. Gerraty# The guard variable cannot be a number, as numbers are interpreted
61*d5e0a182SSimon J. Gerraty# differently from bare words.
62*d5e0a182SSimon J. GerratyCASES+=	variable-ifndef-one
63*d5e0a182SSimon J. GerratyLINES.variable-ifndef-one= \
64*d5e0a182SSimon J. Gerraty	'.ifndef 1' \
65*d5e0a182SSimon J. Gerraty	'.endif'
66*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-one.tmp, line 1
67*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-one.tmp, line 1
68*d5e0a182SSimon J. Gerraty
69148ee845SSimon J. Gerraty# Comments and empty lines do not affect the multiple-inclusion guard.
70*d5e0a182SSimon J. GerratyCASES+=	comments
71148ee845SSimon J. GerratyLINES.comments= \
72148ee845SSimon J. Gerraty	'\# comment' \
73148ee845SSimon J. Gerraty	'' \
74148ee845SSimon J. Gerraty	'.ifndef COMMENTS' \
75148ee845SSimon J. Gerraty	'\# comment' \
76148ee845SSimon J. Gerraty	'COMMENTS=\#comment' \
77148ee845SSimon J. Gerraty	'.endif' \
78148ee845SSimon J. Gerraty	'\# comment'
79148ee845SSimon J. Gerraty# expect: Parse_PushInput: file comments.tmp, line 1
80148ee845SSimon J. Gerraty# expect: Skipping 'comments.tmp' because 'COMMENTS' is defined
81148ee845SSimon J. Gerraty
82148ee845SSimon J. Gerraty# An alternative form uses the 'defined' function.  It is more verbose than
83148ee845SSimon J. Gerraty# the canonical form but avoids the '.ifndef' directive, as that directive is
84148ee845SSimon J. Gerraty# not commonly used.
85*d5e0a182SSimon J. GerratyCASES+=	variable-if
86148ee845SSimon J. GerratyLINES.variable-if= \
87148ee845SSimon J. Gerraty	'.if !defined(VARIABLE_IF)' \
88148ee845SSimon J. Gerraty	'VARIABLE_IF=' \
89148ee845SSimon J. Gerraty	'.endif'
90148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-if.tmp, line 1
91148ee845SSimon J. Gerraty# expect: Skipping 'variable-if.tmp' because 'VARIABLE_IF' is defined
92148ee845SSimon J. Gerraty
93148ee845SSimon J. Gerraty# A file that reuses a guard from a previous file (or whose guard is defined
94148ee845SSimon J. Gerraty# for any other reason) is only processed once, to see whether it is guarded.
95148ee845SSimon J. Gerraty# Its content is skipped, therefore the syntax error is not detected.
96*d5e0a182SSimon J. GerratyCASES+=	variable-if-reuse
97148ee845SSimon J. GerratyLINES.variable-if-reuse= \
98148ee845SSimon J. Gerraty	'.if !defined(VARIABLE_IF)' \
99148ee845SSimon J. Gerraty	'syntax error' \
100148ee845SSimon J. Gerraty	'.endif'
101148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-reuse.tmp, line 1
102148ee845SSimon J. Gerraty# expect: Skipping 'variable-if-reuse.tmp' because 'VARIABLE_IF' is defined
103148ee845SSimon J. Gerraty
104148ee845SSimon J. Gerraty# Triple negation is so uncommon that it's not recognized, even though it has
105148ee845SSimon J. Gerraty# the same effect as a single negation.
106*d5e0a182SSimon J. GerratyCASES+=	variable-if-triple-negation
107148ee845SSimon J. GerratyLINES.variable-if-triple-negation= \
108148ee845SSimon J. Gerraty	'.if !!!defined(VARIABLE_IF_TRIPLE_NEGATION)' \
109148ee845SSimon J. Gerraty	'VARIABLE_IF_TRIPLE_NEGATION=' \
110148ee845SSimon J. Gerraty	'.endif'
111148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-triple-negation.tmp, line 1
112148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-triple-negation.tmp, line 1
113148ee845SSimon J. Gerraty
114*d5e0a182SSimon J. Gerraty# If the guard variable is enclosed in spaces, it does not have an effect, as
115*d5e0a182SSimon J. Gerraty# that form is not common in practice.
116*d5e0a182SSimon J. GerratyCASES+=	variable-if-spaced
117*d5e0a182SSimon J. GerratyLINES.variable-if-spaced= \
118*d5e0a182SSimon J. Gerraty	'.if !defined( VARIABLE_IF_SPACED )' \
119*d5e0a182SSimon J. Gerraty	'VARIABLE_IF_SPACED=' \
120*d5e0a182SSimon J. Gerraty	'.endif'
121*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-spaced.tmp, line 1
122*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-spaced.tmp, line 1
123*d5e0a182SSimon J. Gerraty
124*d5e0a182SSimon J. Gerraty# If the guard variable condition is enclosed in parentheses, it does not have
125*d5e0a182SSimon J. Gerraty# an effect, as that form is not common in practice.
126*d5e0a182SSimon J. GerratyCASES+=	variable-if-parenthesized
127*d5e0a182SSimon J. GerratyLINES.variable-if-parenthesized= \
128*d5e0a182SSimon J. Gerraty	'.if (!defined(VARIABLE_IF_PARENTHESIZED))' \
129*d5e0a182SSimon J. Gerraty	'VARIABLE_IF_PARENTHESIZED=' \
130*d5e0a182SSimon J. Gerraty	'.endif'
131*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-parenthesized.tmp, line 1
132*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-parenthesized.tmp, line 1
133*d5e0a182SSimon J. Gerraty
134148ee845SSimon J. Gerraty# A conditional other than '.if' or '.ifndef' does not guard the file, even if
135148ee845SSimon J. Gerraty# it is otherwise equivalent to the above accepted forms.
136*d5e0a182SSimon J. GerratyCASES+=	variable-ifdef-negated
137148ee845SSimon J. GerratyLINES.variable-ifdef-negated= \
138148ee845SSimon J. Gerraty	'.ifdef !VARIABLE_IFDEF_NEGATED' \
139148ee845SSimon J. Gerraty	'VARIABLE_IFDEF_NEGATED=' \
140148ee845SSimon J. Gerraty	'.endif'
141148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifdef-negated.tmp, line 1
142148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifdef-negated.tmp, line 1
143148ee845SSimon J. Gerraty
144148ee845SSimon J. Gerraty# The variable names in the '.if' and the assignment must be the same.
145*d5e0a182SSimon J. GerratyCASES+=	variable-name-mismatch
146148ee845SSimon J. GerratyLINES.variable-name-mismatch= \
147148ee845SSimon J. Gerraty	'.ifndef VARIABLE_NAME_MISMATCH' \
148148ee845SSimon J. Gerraty	'VARIABLE_NAME_DIFFERENT=' \
149148ee845SSimon J. Gerraty	'.endif'
150148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-name-mismatch.tmp, line 1
151148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-name-mismatch.tmp, line 1
152148ee845SSimon J. Gerraty
153*d5e0a182SSimon J. Gerraty# If the guard variable condition is enclosed in parentheses, it does not have
154*d5e0a182SSimon J. Gerraty# an effect, as that form is not common in practice.
155*d5e0a182SSimon J. GerratyCASES+=	variable-ifndef-parenthesized
156*d5e0a182SSimon J. GerratyLINES.variable-ifndef-parenthesized= \
157*d5e0a182SSimon J. Gerraty	'.ifndef (VARIABLE_IFNDEF_PARENTHESIZED)' \
158*d5e0a182SSimon J. Gerraty	'VARIABLE_IFNDEF_PARENTHESIZED=' \
159*d5e0a182SSimon J. Gerraty	'.endif'
160*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-parenthesized.tmp, line 1
161*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-parenthesized.tmp, line 1
162*d5e0a182SSimon J. Gerraty
163148ee845SSimon J. Gerraty# The variable name '!VARNAME' cannot be used in an '.ifndef' directive, as
164148ee845SSimon J. Gerraty# the '!' would be a negation.  It is syntactically valid in a '.if !defined'
16598875883SSimon J. Gerraty# condition, but this case is so uncommon that the guard mechanism doesn't
16698875883SSimon J. Gerraty# accept '!' in the guard variable name. Furthermore, when defining the
16798875883SSimon J. Gerraty# variable, the character '!' has to be escaped, to prevent it from being
16898875883SSimon J. Gerraty# interpreted as the '!' dependency operator.
169*d5e0a182SSimon J. GerratyCASES+=	variable-name-exclamation
170148ee845SSimon J. GerratyLINES.variable-name-exclamation= \
171148ee845SSimon J. Gerraty	'.if !defined(!VARIABLE_NAME_EXCLAMATION)' \
172148ee845SSimon J. Gerraty	'${:U!}VARIABLE_NAME_EXCLAMATION=' \
173148ee845SSimon J. Gerraty	'.endif'
174148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-name-exclamation.tmp, line 1
175148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-name-exclamation.tmp, line 1
176148ee845SSimon J. Gerraty
177*d5e0a182SSimon J. Gerraty# In general, a variable name can contain a '!' in the middle, as that
178*d5e0a182SSimon J. Gerraty# character is interpreted as an ordinary character in conditions as well as
179*d5e0a182SSimon J. Gerraty# on the left side of a variable assignment.  For guard variable names, the
180*d5e0a182SSimon J. Gerraty# '!' is not supported in any place, though.
181*d5e0a182SSimon J. GerratyCASES+=	variable-name-exclamation-middle
182148ee845SSimon J. GerratyLINES.variable-name-exclamation-middle= \
183148ee845SSimon J. Gerraty	'.ifndef VARIABLE_NAME!MIDDLE' \
184148ee845SSimon J. Gerraty	'VARIABLE_NAME!MIDDLE=' \
185148ee845SSimon J. Gerraty	'.endif'
186148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-name-exclamation-middle.tmp, line 1
187148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-name-exclamation-middle.tmp, line 1
188148ee845SSimon J. Gerraty
189148ee845SSimon J. Gerraty# A variable name can contain balanced parentheses, at least in conditions and
190148ee845SSimon J. Gerraty# on the left side of a variable assignment.  There are enough places in make
191148ee845SSimon J. Gerraty# where parentheses or braces are handled inconsistently to make this naming
192148ee845SSimon J. Gerraty# choice a bad idea, therefore these characters are not allowed in guard
193148ee845SSimon J. Gerraty# variable names.
194*d5e0a182SSimon J. GerratyCASES+=	variable-name-parentheses
195148ee845SSimon J. GerratyLINES.variable-name-parentheses= \
196148ee845SSimon J. Gerraty	'.ifndef VARIABLE_NAME(&)PARENTHESES' \
197148ee845SSimon J. Gerraty	'VARIABLE_NAME(&)PARENTHESES=' \
198148ee845SSimon J. Gerraty	'.endif'
199148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-name-parentheses.tmp, line 1
200148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-name-parentheses.tmp, line 1
201148ee845SSimon J. Gerraty
202148ee845SSimon J. Gerraty# The guard condition must consist of only the guard variable, nothing else.
203*d5e0a182SSimon J. GerratyCASES+=	variable-ifndef-plus
204148ee845SSimon J. GerratyLINES.variable-ifndef-plus= \
205148ee845SSimon J. Gerraty	'.ifndef VARIABLE_IFNDEF_PLUS && VARIABLE_IFNDEF_SECOND' \
206148ee845SSimon J. Gerraty	'VARIABLE_IFNDEF_PLUS=' \
207148ee845SSimon J. Gerraty	'VARIABLE_IFNDEF_SECOND=' \
208148ee845SSimon J. Gerraty	'.endif'
209148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-plus.tmp, line 1
210148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-plus.tmp, line 1
211148ee845SSimon J. Gerraty
212148ee845SSimon J. Gerraty# The guard condition must consist of only the guard variable, nothing else.
213*d5e0a182SSimon J. GerratyCASES+=	variable-if-plus
214148ee845SSimon J. GerratyLINES.variable-if-plus= \
215148ee845SSimon J. Gerraty	'.if !defined(VARIABLE_IF_PLUS) && !defined(VARIABLE_IF_SECOND)' \
216148ee845SSimon J. Gerraty	'VARIABLE_IF_PLUS=' \
217148ee845SSimon J. Gerraty	'VARIABLE_IF_SECOND=' \
218148ee845SSimon J. Gerraty	'.endif'
219148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-plus.tmp, line 1
220148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-plus.tmp, line 1
221148ee845SSimon J. Gerraty
222148ee845SSimon J. Gerraty# The variable name in an '.ifndef' guard must be given directly, it must not
223148ee845SSimon J. Gerraty# contain any '$' expression.
224*d5e0a182SSimon J. GerratyCASES+=	variable-ifndef-indirect
225148ee845SSimon J. GerratyLINES.variable-ifndef-indirect= \
226148ee845SSimon J. Gerraty	'.ifndef $${VARIABLE_IFNDEF_INDIRECT:L}' \
227148ee845SSimon J. Gerraty	'VARIABLE_IFNDEF_INDIRECT=' \
228148ee845SSimon J. Gerraty	'.endif'
229148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-indirect.tmp, line 1
230148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-ifndef-indirect.tmp, line 1
231148ee845SSimon J. Gerraty
232148ee845SSimon J. Gerraty# The variable name in an '.if' guard must be given directly, it must not
233148ee845SSimon J. Gerraty# contain any '$' expression.
234*d5e0a182SSimon J. GerratyCASES+=	variable-if-indirect
235148ee845SSimon J. GerratyLINES.variable-if-indirect= \
236148ee845SSimon J. Gerraty	'.if !defined($${VARIABLE_IF_INDIRECT:L})' \
237148ee845SSimon J. Gerraty	'VARIABLE_IF_INDIRECT=' \
238148ee845SSimon J. Gerraty	'.endif'
239148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-indirect.tmp, line 1
240148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-if-indirect.tmp, line 1
241148ee845SSimon J. Gerraty
242148ee845SSimon J. Gerraty# The variable name in the guard condition must only contain alphanumeric
24398875883SSimon J. Gerraty# characters and underscores.  The place where the guard variable is defined
24498875883SSimon J. Gerraty# is more flexible, as long as the variable is defined at the point where the
24598875883SSimon J. Gerraty# file is included the next time.
246*d5e0a182SSimon J. GerratyCASES+=	variable-assign-indirect
247148ee845SSimon J. GerratyLINES.variable-assign-indirect= \
248148ee845SSimon J. Gerraty	'.ifndef VARIABLE_ASSIGN_INDIRECT' \
249148ee845SSimon J. Gerraty	'$${VARIABLE_ASSIGN_INDIRECT:L}=' \
250148ee845SSimon J. Gerraty	'.endif'
251148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-assign-indirect.tmp, line 1
252148ee845SSimon J. Gerraty# expect: Skipping 'variable-assign-indirect.tmp' because 'VARIABLE_ASSIGN_INDIRECT' is defined
253148ee845SSimon J. Gerraty
254148ee845SSimon J. Gerraty# The time at which the guard variable is defined doesn't matter, as long as
255148ee845SSimon J. Gerraty# it is defined at the point where the file is included the next time.
256*d5e0a182SSimon J. GerratyCASES+=	variable-assign-late
257148ee845SSimon J. GerratyLINES.variable-assign-late= \
258148ee845SSimon J. Gerraty	'.ifndef VARIABLE_ASSIGN_LATE' \
259148ee845SSimon J. Gerraty	'VARIABLE_ASSIGN_LATE_OTHER=' \
260148ee845SSimon J. Gerraty	'VARIABLE_ASSIGN_LATE=' \
261148ee845SSimon J. Gerraty	'.endif'
262148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-assign-late.tmp, line 1
263148ee845SSimon J. Gerraty# expect: Skipping 'variable-assign-late.tmp' because 'VARIABLE_ASSIGN_LATE' is defined
264148ee845SSimon J. Gerraty
265148ee845SSimon J. Gerraty# The time at which the guard variable is defined doesn't matter, as long as
266148ee845SSimon J. Gerraty# it is defined at the point where the file is included the next time.
267*d5e0a182SSimon J. GerratyCASES+=	variable-assign-nested
268148ee845SSimon J. GerratyLINES.variable-assign-nested= \
269148ee845SSimon J. Gerraty	'.ifndef VARIABLE_ASSIGN_NESTED' \
270148ee845SSimon J. Gerraty	'.  if 1' \
271148ee845SSimon J. Gerraty	'.    for i in once' \
272148ee845SSimon J. Gerraty	'VARIABLE_ASSIGN_NESTED=' \
273148ee845SSimon J. Gerraty	'.    endfor' \
274148ee845SSimon J. Gerraty	'.  endif' \
275148ee845SSimon J. Gerraty	'.endif'
276148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-assign-nested.tmp, line 1
277148ee845SSimon J. Gerraty# expect: Skipping 'variable-assign-nested.tmp' because 'VARIABLE_ASSIGN_NESTED' is defined
278148ee845SSimon J. Gerraty
279148ee845SSimon J. Gerraty# If the guard variable is defined before the file is included for the first
280148ee845SSimon J. Gerraty# time, the file is considered guarded as well.  In such a case, the parser
281148ee845SSimon J. Gerraty# skips almost all lines, as they are irrelevant, but the structure of the
282148ee845SSimon J. Gerraty# top-level '.if/.endif' conditional can be determined reliably enough to
283148ee845SSimon J. Gerraty# decide whether the file is guarded.
284*d5e0a182SSimon J. GerratyCASES+=	variable-already-defined
285148ee845SSimon J. GerratyLINES.variable-already-defined= \
286148ee845SSimon J. Gerraty	'.ifndef VARIABLE_ALREADY_DEFINED' \
287148ee845SSimon J. Gerraty	'VARIABLE_ALREADY_DEFINED=' \
288148ee845SSimon J. Gerraty	'.endif'
289148ee845SSimon J. GerratyVARIABLE_ALREADY_DEFINED=
290148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-already-defined.tmp, line 1
291148ee845SSimon J. Gerraty# expect: Skipping 'variable-already-defined.tmp' because 'VARIABLE_ALREADY_DEFINED' is defined
292148ee845SSimon J. Gerraty
293148ee845SSimon J. Gerraty# If the guard variable is defined before the file is included the first time,
294148ee845SSimon J. Gerraty# the file is processed but its content is skipped.  If that same guard
295148ee845SSimon J. Gerraty# variable is undefined when the file is included the second time, the file is
296148ee845SSimon J. Gerraty# processed as usual.
297*d5e0a182SSimon J. GerratyCASES+=	variable-defined-then-undefined
298148ee845SSimon J. GerratyLINES.variable-defined-then-undefined= \
299148ee845SSimon J. Gerraty	'.ifndef VARIABLE_DEFINED_THEN_UNDEFINED' \
300148ee845SSimon J. Gerraty	'.endif'
301148ee845SSimon J. GerratyVARIABLE_DEFINED_THEN_UNDEFINED=
302148ee845SSimon J. GerratyUNDEF_BETWEEN.variable-defined-then-undefined= \
303148ee845SSimon J. Gerraty	VARIABLE_DEFINED_THEN_UNDEFINED
304148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-defined-then-undefined.tmp, line 1
305148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-defined-then-undefined.tmp, line 1
306148ee845SSimon J. Gerraty
307148ee845SSimon J. Gerraty# The whole file content must be guarded by a single '.if' conditional, not by
30898875883SSimon J. Gerraty# several, as each of these conditionals would require its separate guard.
30998875883SSimon J. Gerraty# This case is not expected to occur in practice, as the two parts would
31098875883SSimon J. Gerraty# rather be split into separate files.
311*d5e0a182SSimon J. GerratyCASES+=	variable-two-times
312148ee845SSimon J. GerratyLINES.variable-two-times= \
313148ee845SSimon J. Gerraty	'.ifndef VARIABLE_TWO_TIMES_1' \
314148ee845SSimon J. Gerraty	'VARIABLE_TWO_TIMES_1=' \
315148ee845SSimon J. Gerraty	'.endif' \
316148ee845SSimon J. Gerraty	'.ifndef VARIABLE_TWO_TIMES_2' \
317148ee845SSimon J. Gerraty	'VARIABLE_TWO_TIMES_2=' \
318148ee845SSimon J. Gerraty	'.endif'
319148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-two-times.tmp, line 1
320148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-two-times.tmp, line 1
321148ee845SSimon J. Gerraty
322148ee845SSimon J. Gerraty# When multiple files use the same guard variable name, the optimization of
323148ee845SSimon J. Gerraty# skipping the file affects each of these files.
324148ee845SSimon J. Gerraty#
325148ee845SSimon J. Gerraty# Choosing unique guard names is the responsibility of the makefile authors.
326148ee845SSimon J. Gerraty# A typical pattern of guard variable names is '${PROJECT}_${DIR}_${FILE}_MK'.
327148ee845SSimon J. Gerraty# System-provided files typically start the guard names with '_'.
328*d5e0a182SSimon J. GerratyCASES+=	variable-clash
329148ee845SSimon J. GerratyLINES.variable-clash= \
330148ee845SSimon J. Gerraty	${LINES.variable-if}
331148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-clash.tmp, line 1
332148ee845SSimon J. Gerraty# expect: Skipping 'variable-clash.tmp' because 'VARIABLE_IF' is defined
333148ee845SSimon J. Gerraty
334148ee845SSimon J. Gerraty# The conditional must come before the assignment, otherwise the conditional
335148ee845SSimon J. Gerraty# is useless, as it always evaluates to false.
336*d5e0a182SSimon J. GerratyCASES+=	variable-swapped
337148ee845SSimon J. GerratyLINES.variable-swapped= \
338148ee845SSimon J. Gerraty	'SWAPPED=' \
339148ee845SSimon J. Gerraty	'.ifndef SWAPPED' \
340148ee845SSimon J. Gerraty	'.  error' \
341148ee845SSimon J. Gerraty	'.endif'
342148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-swapped.tmp, line 1
343148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-swapped.tmp, line 1
344148ee845SSimon J. Gerraty
345148ee845SSimon J. Gerraty# If the guard variable is undefined between the first and the second time the
346148ee845SSimon J. Gerraty# file is included, the guarded file is included again.
347*d5e0a182SSimon J. GerratyCASES+=	variable-undef-between
348148ee845SSimon J. GerratyLINES.variable-undef-between= \
349148ee845SSimon J. Gerraty	'.ifndef VARIABLE_UNDEF_BETWEEN' \
350148ee845SSimon J. Gerraty	'VARIABLE_UNDEF_BETWEEN=' \
351148ee845SSimon J. Gerraty	'.endif'
352148ee845SSimon J. GerratyUNDEF_BETWEEN.variable-undef-between= \
353148ee845SSimon J. Gerraty	VARIABLE_UNDEF_BETWEEN
354148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-undef-between.tmp, line 1
355148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-undef-between.tmp, line 1
356148ee845SSimon J. Gerraty
357148ee845SSimon J. Gerraty# If the guard variable is undefined while the file is included the first
358148ee845SSimon J. Gerraty# time, the guard does not have an effect, and the file is included again.
359*d5e0a182SSimon J. GerratyCASES+=	variable-undef-inside
360148ee845SSimon J. GerratyLINES.variable-undef-inside= \
361148ee845SSimon J. Gerraty	'.ifndef VARIABLE_UNDEF_INSIDE' \
362148ee845SSimon J. Gerraty	'VARIABLE_UNDEF_INSIDE=' \
363148ee845SSimon J. Gerraty	'.undef VARIABLE_UNDEF_INSIDE' \
364148ee845SSimon J. Gerraty	'.endif'
365148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-undef-inside.tmp, line 1
366148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-undef-inside.tmp, line 1
367148ee845SSimon J. Gerraty
368148ee845SSimon J. Gerraty# If the file does not define the guard variable, the guard does not have an
369148ee845SSimon J. Gerraty# effect, and the file is included again.
370*d5e0a182SSimon J. GerratyCASES+=	variable-not-defined
371148ee845SSimon J. GerratyLINES.variable-not-defined= \
372148ee845SSimon J. Gerraty	'.ifndef VARIABLE_NOT_DEFINED' \
373148ee845SSimon J. Gerraty	'.endif'
374148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-not-defined.tmp, line 1
375148ee845SSimon J. Gerraty# expect: Parse_PushInput: file variable-not-defined.tmp, line 1
376148ee845SSimon J. Gerraty
377148ee845SSimon J. Gerraty# The outermost '.if' must not have an '.elif' branch.
378*d5e0a182SSimon J. GerratyCASES+=	elif
37998875883SSimon J. GerratyLINES.elif= \
38098875883SSimon J. Gerraty	'.ifndef ELIF' \
38198875883SSimon J. Gerraty	'ELIF=' \
382148ee845SSimon J. Gerraty	'.elif 1' \
383148ee845SSimon J. Gerraty	'.endif'
38498875883SSimon J. Gerraty# expect: Parse_PushInput: file elif.tmp, line 1
38598875883SSimon J. Gerraty# expect: Parse_PushInput: file elif.tmp, line 1
386148ee845SSimon J. Gerraty
387148ee845SSimon J. Gerraty# When a file with an '.if/.elif/.endif' conditional at the top level is
388148ee845SSimon J. Gerraty# included, it is never optimized, as one of its branches is taken.
389*d5e0a182SSimon J. GerratyCASES+=	elif-reuse
39098875883SSimon J. GerratyLINES.elif-reuse= \
39198875883SSimon J. Gerraty	'.ifndef ELIF' \
392148ee845SSimon J. Gerraty	'syntax error' \
393148ee845SSimon J. Gerraty	'.elif 1' \
394148ee845SSimon J. Gerraty	'.endif'
39598875883SSimon J. Gerraty# expect: Parse_PushInput: file elif-reuse.tmp, line 1
39698875883SSimon J. Gerraty# expect: Parse_PushInput: file elif-reuse.tmp, line 1
397148ee845SSimon J. Gerraty
398148ee845SSimon J. Gerraty# The outermost '.if' must not have an '.else' branch.
399*d5e0a182SSimon J. GerratyCASES+=	else
40098875883SSimon J. GerratyLINES.else= \
40198875883SSimon J. Gerraty	'.ifndef ELSE' \
40298875883SSimon J. Gerraty	'ELSE=' \
403148ee845SSimon J. Gerraty	'.else' \
404148ee845SSimon J. Gerraty	'.endif'
40598875883SSimon J. Gerraty# expect: Parse_PushInput: file else.tmp, line 1
40698875883SSimon J. Gerraty# expect: Parse_PushInput: file else.tmp, line 1
407148ee845SSimon J. Gerraty
408148ee845SSimon J. Gerraty# When a file with an '.if/.else/.endif' conditional at the top level is
409148ee845SSimon J. Gerraty# included, it is never optimized, as one of its branches is taken.
410*d5e0a182SSimon J. GerratyCASES+=	else-reuse
41198875883SSimon J. GerratyLINES.else-reuse= \
41298875883SSimon J. Gerraty	'.ifndef ELSE' \
413148ee845SSimon J. Gerraty	'syntax error' \
414148ee845SSimon J. Gerraty	'.else' \
415148ee845SSimon J. Gerraty	'.endif'
41698875883SSimon J. Gerraty# expect: Parse_PushInput: file else-reuse.tmp, line 1
41798875883SSimon J. Gerraty# expect: Parse_PushInput: file else-reuse.tmp, line 1
418148ee845SSimon J. Gerraty
419148ee845SSimon J. Gerraty# The inner '.if' directives may have an '.elif' or '.else', and it doesn't
420148ee845SSimon J. Gerraty# matter which of their branches are taken.
421*d5e0a182SSimon J. GerratyCASES+=	inner-if-elif-else
422148ee845SSimon J. GerratyLINES.inner-if-elif-else= \
423148ee845SSimon J. Gerraty	'.ifndef INNER_IF_ELIF_ELSE' \
424148ee845SSimon J. Gerraty	'INNER_IF_ELIF_ELSE=' \
425148ee845SSimon J. Gerraty	'.  if 0' \
426148ee845SSimon J. Gerraty	'.  elif 0' \
427148ee845SSimon J. Gerraty	'.  else' \
428148ee845SSimon J. Gerraty	'.  endif' \
429148ee845SSimon J. Gerraty	'.  if 0' \
430148ee845SSimon J. Gerraty	'.  elif 1' \
431148ee845SSimon J. Gerraty	'.  else' \
432148ee845SSimon J. Gerraty	'.  endif' \
433148ee845SSimon J. Gerraty	'.  if 1' \
434148ee845SSimon J. Gerraty	'.  elif 1' \
435148ee845SSimon J. Gerraty	'.  else' \
436148ee845SSimon J. Gerraty	'.  endif' \
437148ee845SSimon J. Gerraty	'.endif'
438148ee845SSimon J. Gerraty# expect: Parse_PushInput: file inner-if-elif-else.tmp, line 1
439148ee845SSimon J. Gerraty# expect: Skipping 'inner-if-elif-else.tmp' because 'INNER_IF_ELIF_ELSE' is defined
440148ee845SSimon J. Gerraty
441148ee845SSimon J. Gerraty# The guard can also be a target instead of a variable.  Using a target as a
442148ee845SSimon J. Gerraty# guard has the benefit that a target cannot be undefined once it is defined.
443148ee845SSimon J. Gerraty# The target should be declared '.NOTMAIN'.  Since the target names are
444148ee845SSimon J. Gerraty# usually chosen according to a pattern that doesn't interfere with real
445148ee845SSimon J. Gerraty# target names, they don't need to be declared '.PHONY' as they don't generate
446148ee845SSimon J. Gerraty# filesystem operations.
447*d5e0a182SSimon J. GerratyCASES+=	target
448148ee845SSimon J. GerratyLINES.target= \
449148ee845SSimon J. Gerraty	'.if !target(__target.tmp__)' \
450148ee845SSimon J. Gerraty	'__target.tmp__: .NOTMAIN' \
451148ee845SSimon J. Gerraty	'.endif'
452148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target.tmp, line 1
453148ee845SSimon J. Gerraty# expect: Skipping 'target.tmp' because '__target.tmp__' is defined
454148ee845SSimon J. Gerraty
455148ee845SSimon J. Gerraty# When used for system files, the target name may include '<' and '>', for
456148ee845SSimon J. Gerraty# symmetry with the '.include <sys.mk>' directive.  The characters '<' and '>'
457148ee845SSimon J. Gerraty# are ordinary characters.
458*d5e0a182SSimon J. GerratyCASES+=	target-sys
459148ee845SSimon J. GerratyLINES.target-sys= \
460148ee845SSimon J. Gerraty	'.if !target(__<target-sys.tmp>__)' \
461148ee845SSimon J. Gerraty	'__<target-sys.tmp>__: .NOTMAIN' \
462148ee845SSimon J. Gerraty	'.endif'
463148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-sys.tmp, line 1
464148ee845SSimon J. Gerraty# expect: Skipping 'target-sys.tmp' because '__<target-sys.tmp>__' is defined
465148ee845SSimon J. Gerraty
466148ee845SSimon J. Gerraty# The target name may include variable references.  These references are
467148ee845SSimon J. Gerraty# expanded as usual.  Due to the current implementation, the expressions are
468148ee845SSimon J. Gerraty# evaluated twice:  Once for checking whether the condition evaluates to true,
469148ee845SSimon J. Gerraty# and once for determining the guard name.  This double evaluation should not
470148ee845SSimon J. Gerraty# matter in practice, as guard expressions are expected to be simple,
471148ee845SSimon J. Gerraty# deterministic and without side effects.
472*d5e0a182SSimon J. GerratyCASES+=	target-indirect
473148ee845SSimon J. GerratyLINES.target-indirect= \
474148ee845SSimon J. Gerraty	'.if !target($${target-indirect.tmp:L})' \
475148ee845SSimon J. Gerraty	'target-indirect.tmp: .NOTMAIN' \
476148ee845SSimon J. Gerraty	'.endif'
477148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-indirect.tmp, line 1
478148ee845SSimon J. Gerraty# expect: Skipping 'target-indirect.tmp' because 'target-indirect.tmp' is defined
479148ee845SSimon J. Gerraty
480148ee845SSimon J. Gerraty# A common form of guard target is __${.PARSEFILE}__.  This form can only be
481148ee845SSimon J. Gerraty# used if all files using this form have unique basenames.  To get a robust
482148ee845SSimon J. Gerraty# pattern based on the same idea, use __${.PARSEDIR}/${.PARSEFILE}__ instead.
483148ee845SSimon J. Gerraty# This form does not work when the basename contains whitespace characters, as
484148ee845SSimon J. Gerraty# it is not possible to define a target with whitespace, not even by cheating.
485*d5e0a182SSimon J. GerratyCASES+=	target-indirect-PARSEFILE
486148ee845SSimon J. GerratyLINES.target-indirect-PARSEFILE= \
487148ee845SSimon J. Gerraty	'.if !target(__$${.PARSEFILE}__)' \
488148ee845SSimon J. Gerraty	'__$${.PARSEFILE}__: .NOTMAIN' \
489148ee845SSimon J. Gerraty	'.endif'
490148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-indirect-PARSEFILE.tmp, line 1
491148ee845SSimon J. Gerraty# expect: Skipping 'target-indirect-PARSEFILE.tmp' because '__target-indirect-PARSEFILE.tmp__' is defined
492148ee845SSimon J. Gerraty
493148ee845SSimon J. Gerraty# Two files with different basenames can both use the same syntactic pattern
494148ee845SSimon J. Gerraty# for the target guard name, as the expressions expand to different strings.
495*d5e0a182SSimon J. GerratyCASES+=	target-indirect-PARSEFILE2
496148ee845SSimon J. GerratyLINES.target-indirect-PARSEFILE2= \
497148ee845SSimon J. Gerraty	'.if !target(__$${.PARSEFILE}__)' \
498148ee845SSimon J. Gerraty	'__$${.PARSEFILE}__: .NOTMAIN' \
499148ee845SSimon J. Gerraty	'.endif'
500148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-indirect-PARSEFILE2.tmp, line 1
501148ee845SSimon J. Gerraty# expect: Skipping 'target-indirect-PARSEFILE2.tmp' because '__target-indirect-PARSEFILE2.tmp__' is defined
502148ee845SSimon J. Gerraty
503148ee845SSimon J. Gerraty# Using plain .PARSEFILE without .PARSEDIR leads to name clashes.  The include
504148ee845SSimon J. Gerraty# guard is the same as in the test case 'target-indirect-PARSEFILE', as the
50598875883SSimon J. Gerraty# guard name only contains the basename but not the directory name.  So even
506*d5e0a182SSimon J. Gerraty# without defining the guard target, the file is considered guarded.
507*d5e0a182SSimon J. GerratyCASES+=	subdir/target-indirect-PARSEFILE
508148ee845SSimon J. GerratyLINES.subdir/target-indirect-PARSEFILE= \
509148ee845SSimon J. Gerraty	'.if !target(__$${.PARSEFILE}__)' \
510148ee845SSimon J. Gerraty	'.endif'
511148ee845SSimon J. Gerraty# expect: Parse_PushInput: file subdir/target-indirect-PARSEFILE.tmp, line 1
512148ee845SSimon J. Gerraty# expect: Skipping 'subdir/target-indirect-PARSEFILE.tmp' because '__target-indirect-PARSEFILE.tmp__' is defined
513148ee845SSimon J. Gerraty
514148ee845SSimon J. Gerraty# Another common form of guard target is __${.PARSEDIR}/${.PARSEFILE}__
51598875883SSimon J. Gerraty# or __${.PARSEDIR:tA}/${.PARSEFILE}__ to be truly unique.
516*d5e0a182SSimon J. GerratyCASES+=	target-indirect-PARSEDIR-PARSEFILE
517148ee845SSimon J. GerratyLINES.target-indirect-PARSEDIR-PARSEFILE= \
518148ee845SSimon J. Gerraty	'.if !target(__$${.PARSEDIR}/$${.PARSEFILE}__)' \
519148ee845SSimon J. Gerraty	'__$${.PARSEDIR}/$${.PARSEFILE}__: .NOTMAIN' \
520148ee845SSimon J. Gerraty	'.endif'
521148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-indirect-PARSEDIR-PARSEFILE.tmp, line 1
522148ee845SSimon J. Gerraty# expect: Skipping 'target-indirect-PARSEDIR-PARSEFILE.tmp' because '__target-indirect-PARSEDIR-PARSEFILE.tmp__' is defined
523148ee845SSimon J. Gerraty# The actual target starts with '__${.OBJDIR}/', see the .rawout file, but the
524148ee845SSimon J. Gerraty# string '${.OBJDIR}/' gets stripped in post processing.
525148ee845SSimon J. Gerraty
526148ee845SSimon J. Gerraty# Using the combination of '.PARSEDIR' and '.PARSEFILE', a file in a
527148ee845SSimon J. Gerraty# subdirectory gets a different guard target name than the previous one.
528*d5e0a182SSimon J. GerratyCASES+=	subdir/target-indirect-PARSEDIR-PARSEFILE
529148ee845SSimon J. GerratyLINES.subdir/target-indirect-PARSEDIR-PARSEFILE= \
530148ee845SSimon J. Gerraty	'.if !target(__$${.PARSEDIR}/$${.PARSEFILE}__)' \
531148ee845SSimon J. Gerraty	'__$${.PARSEDIR}/$${.PARSEFILE}__: .NOTMAIN' \
532148ee845SSimon J. Gerraty	'.endif'
533148ee845SSimon J. Gerraty# expect: Parse_PushInput: file subdir/target-indirect-PARSEDIR-PARSEFILE.tmp, line 1
534148ee845SSimon J. Gerraty# expect: Skipping 'subdir/target-indirect-PARSEDIR-PARSEFILE.tmp' because '__subdir/target-indirect-PARSEDIR-PARSEFILE.tmp__' is defined
535148ee845SSimon J. Gerraty# The actual target starts with '__${.OBJDIR}/', see the .rawout file, but the
536148ee845SSimon J. Gerraty# string '${.OBJDIR}/' gets stripped in post processing.
537148ee845SSimon J. Gerraty
538148ee845SSimon J. Gerraty# If the guard target is not defined when including the file the next time,
539148ee845SSimon J. Gerraty# the file is processed again.
540*d5e0a182SSimon J. GerratyCASES+=	target-unguarded
541148ee845SSimon J. GerratyLINES.target-unguarded= \
542148ee845SSimon J. Gerraty	'.if !target(target-unguarded)' \
543148ee845SSimon J. Gerraty	'.endif'
544148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-unguarded.tmp, line 1
545148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-unguarded.tmp, line 1
546148ee845SSimon J. Gerraty
547148ee845SSimon J. Gerraty# The guard condition must consist of only the guard target, nothing else.
548*d5e0a182SSimon J. GerratyCASES+=	target-plus
549148ee845SSimon J. GerratyLINES.target-plus= \
550148ee845SSimon J. Gerraty	'.if !target(target-plus) && 1' \
551148ee845SSimon J. Gerraty	'target-plus: .NOTMAIN' \
552148ee845SSimon J. Gerraty	'.endif'
553148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-plus.tmp, line 1
554148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-plus.tmp, line 1
555148ee845SSimon J. Gerraty
556148ee845SSimon J. Gerraty# If the guard target is defined before the file is included the first time,
55798875883SSimon J. Gerraty# the file is read once and then considered guarded.
558*d5e0a182SSimon J. GerratyCASES+=	target-already-defined
559148ee845SSimon J. GerratyLINES.target-already-defined= \
560148ee845SSimon J. Gerraty	'.if !target(target-already-defined)' \
561148ee845SSimon J. Gerraty	'target-already-defined: .NOTMAIN' \
562148ee845SSimon J. Gerraty	'.endif'
563148ee845SSimon J. Gerratytarget-already-defined: .NOTMAIN
564148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-already-defined.tmp, line 1
565148ee845SSimon J. Gerraty# expect: Skipping 'target-already-defined.tmp' because 'target-already-defined' is defined
566148ee845SSimon J. Gerraty
567148ee845SSimon J. Gerraty# A target name cannot contain the character '!'.  In the condition, the '!'
568148ee845SSimon J. Gerraty# is syntactically valid, but in the dependency declaration line, the '!' is
569148ee845SSimon J. Gerraty# interpreted as the '!' dependency operator, no matter whether it occurs at
570148ee845SSimon J. Gerraty# the beginning or in the middle of a target name.  Escaping it as '${:U!}'
571148ee845SSimon J. Gerraty# doesn't work, as the whole line is first expanded and then scanned for the
572148ee845SSimon J. Gerraty# dependency operator.  Escaping it as '\!' doesn't work either, even though
573148ee845SSimon J. Gerraty# the '\' escapes the '!' from being a dependency operator, but when reading
574148ee845SSimon J. Gerraty# the target name, the '\' is kept, resulting in the target name
575148ee845SSimon J. Gerraty# '\!target-name-exclamation' instead of '!target-name-exclamation'.
576*d5e0a182SSimon J. GerratyCASES+=	target-name-exclamation
577148ee845SSimon J. GerratyLINES.target-name-exclamation= \
578148ee845SSimon J. Gerraty	'.if !target(!target-name-exclamation)' \
579148ee845SSimon J. Gerraty	'\!target-name-exclamation: .NOTMAIN' \
580148ee845SSimon J. Gerraty	'.endif'
581148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-name-exclamation.tmp, line 1
582148ee845SSimon J. Gerraty# expect: Parse_PushInput: file target-name-exclamation.tmp, line 1
583148ee845SSimon J. Gerraty
584*d5e0a182SSimon J. Gerraty# If the guard target name is enclosed in spaces, it does not have an effect,
585*d5e0a182SSimon J. Gerraty# as that form is not common in practice.
586*d5e0a182SSimon J. GerratyCASES+=	target-name-parenthesized
587*d5e0a182SSimon J. GerratyLINES.target-name-parenthesized= \
588*d5e0a182SSimon J. Gerraty	'.if !target( target-name-parenthesized )' \
589*d5e0a182SSimon J. Gerraty	'target-name-parenthesized: .NOTMAIN' \
590*d5e0a182SSimon J. Gerraty	'.endif'
591*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file target-name-parenthesized.tmp, line 1
592*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file target-name-parenthesized.tmp, line 1
593*d5e0a182SSimon J. Gerraty
594*d5e0a182SSimon J. Gerraty# If the guard target condition is enclosed in parentheses, it does not have
595*d5e0a182SSimon J. Gerraty# an effect, as that form is not common in practice.
596*d5e0a182SSimon J. GerratyCASES+=	target-call-parenthesized
597*d5e0a182SSimon J. GerratyLINES.target-call-parenthesized= \
598*d5e0a182SSimon J. Gerraty	'.if (!target(target-call-parenthesized))' \
599*d5e0a182SSimon J. Gerraty	'target-call-parenthesized: .NOTMAIN' \
600*d5e0a182SSimon J. Gerraty	'.endif'
601*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file target-call-parenthesized.tmp, line 1
602*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file target-call-parenthesized.tmp, line 1
603*d5e0a182SSimon J. Gerraty
604*d5e0a182SSimon J. Gerraty# If the '.if' or '.ifndef' directive spans more than a single line, it is
605*d5e0a182SSimon J. Gerraty# still recognized as a guard condition.  This case is entirely uncommon, but
606*d5e0a182SSimon J. Gerraty# at the point where the guard condition is checked, line continuations have
607*d5e0a182SSimon J. Gerraty# already been converted to spaces.
608*d5e0a182SSimon J. GerratyCASES+=	multiline
609*d5e0a182SSimon J. GerratyLINES.multiline= \
610*d5e0a182SSimon J. Gerraty	'.\' \
611*d5e0a182SSimon J. Gerraty	'  ifndef \' \
612*d5e0a182SSimon J. Gerraty	'  MULTILINE' \
613*d5e0a182SSimon J. Gerraty	'MULTILINE=' \
614*d5e0a182SSimon J. Gerraty	'.endif'
615*d5e0a182SSimon J. Gerraty# expect: Parse_PushInput: file multiline.tmp, line 1
616*d5e0a182SSimon J. Gerraty# expect: Skipping 'multiline.tmp' because 'MULTILINE' is defined
617*d5e0a182SSimon J. Gerraty
61898875883SSimon J. Gerraty
619148ee845SSimon J. Gerraty# Now run all test cases by including each of the files twice and looking at
620148ee845SSimon J. Gerraty# the debug output.  The files that properly guard against multiple inclusion
621148ee845SSimon J. Gerraty# generate a 'Skipping' line, the others repeat the 'Parse_PushInput' line.
622148ee845SSimon J. Gerraty#
623148ee845SSimon J. Gerraty# Some debug output lines are suppressed in the .exp file, see ./Makefile.
624*d5e0a182SSimon J. Gerraty.for i in ${CASES}
625148ee845SSimon J. Gerraty.  for fname in $i.tmp
626148ee845SSimon J. Gerraty_:=	${fname:H:N.:@dir@${:!mkdir -p ${dir}!}@}
627148ee845SSimon J. Gerraty_!=	printf '%s\n' ${LINES.$i} > ${fname}
628148ee845SSimon J. Gerraty.MAKEFLAGS: -dp
629148ee845SSimon J. Gerraty.include "${.CURDIR}/${fname}"
630148ee845SSimon J. Gerraty.undef ${UNDEF_BETWEEN.$i:U}
631148ee845SSimon J. Gerraty.include "${.CURDIR}/${fname}"
632148ee845SSimon J. Gerraty.MAKEFLAGS: -d0
633148ee845SSimon J. Gerraty_!=	rm ${fname}
634148ee845SSimon J. Gerraty_:=	${fname:H:N.:@dir@${:!rmdir ${dir}!}@}
635148ee845SSimon J. Gerraty.  endfor
636148ee845SSimon J. Gerraty.endfor
637148ee845SSimon J. Gerraty
638148ee845SSimon J. Gerratyall:
639