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