aboutsummaryrefslogtreecommitdiff
path: root/contrib/bmake/unit-tests/cond-func.mk
blob: aabd31b4db462b5ba938b118831d3c9387c0109e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# $NetBSD: cond-func.mk,v 1.14 2023/11/19 21:47:52 rillig Exp $
#
# Tests for those parts of the functions in .if conditions that are common
# among several functions.
#
# The below test uses the 'defined' function since it has no side-effects.
# The other functions would work equally well, except for 'empty', which
# parses its argument differently from the other functions.
#

DEF=			defined
${:UA B}=		variable name with spaces
${:UVAR(value)}=	variable name with parentheses
${:UVAR{value}}=	variable name with balanced braces

# Really strange variable names must be given indirectly via another variable,
# so that no unbalanced braces appear in the top-level expression.
VARNAME_UNBALANCED_BRACES=	VAR{{{value
${VARNAME_UNBALANCED_BRACES}=	variable name with unbalanced braces

.if !defined(DEF)
.  error
.endif

# Horizontal whitespace (space tab) after the opening parenthesis is ignored.
.if !defined( 	DEF)
.  error
.endif

# Horizontal whitespace (space tab) before the closing parenthesis is ignored.
.if !defined(DEF 	)
.  error
.endif

# The argument of a function must not directly contain whitespace.
# expect+1: Missing closing parenthesis for defined()
.if !defined(A B)
.  error
.endif

# If necessary, the whitespace can be generated by an expression.
.if !defined(${:UA B})
.  error
.endif

# Characters that could be mistaken for operators must not appear directly
# in a function argument.  As with whitespace, these can be generated
# indirectly.
#
# It's not entirely clear why these characters are forbidden.
# The most plausible reason seems to be typo detection.
# expect+1: Missing closing parenthesis for defined()
.if !defined(A&B)
.  error
.endif
# expect+1: Missing closing parenthesis for defined()
.if !defined(A|B)
.  error
.endif

# Even parentheses may appear in variable names.
# They must be balanced though.
.if !defined(VAR(value))
.  error
.endif

# Braces do not have any special meaning when parsing arguments.
.if !defined(VAR{value})
.  error
.endif

# Braces do not have any special meaning when parsing arguments.
# They don't need to be balanced.
.if !defined(VAR{{{value)
.  error
.endif

# There may be spaces around the operators and parentheses, and even
# inside the parentheses.  The spaces inside the parentheses are not
# allowed for the 'empty' function (see cond-func-empty.mk), therefore
# they are typically omitted for the other functions as well.
.if ! defined ( DEF )
.  error
.endif

# The following condition is interpreted as defined(A) && defined(B).
# In lack of a function call expression, each kind of .if directive has a
# default function that is called when a bare word is parsed.  For the plain
# .if directive, this function is defined(); see "struct If ifs" in cond.c.
.if A&B
.  error
.endif

.if defined()
.  error
.else
# expect+1: The empty variable is never defined.
.  info The empty variable is never defined.
.endif

# The plain word 'defined' is interpreted as 'defined(defined)', see
# CondParser_ComparisonOrLeaf.
# That variable is not defined (yet).
.if defined
.  error
.else
# expect+1: A plain function name is parsed as defined(...).
.  info A plain function name is parsed as defined(...).
.endif

# If a variable named 'defined' is actually defined, the bare word 'defined'
# is interpreted as 'defined(defined)', and the condition evaluates to true.
defined=	# defined but empty
.if defined
# expect+1: A plain function name is parsed as defined(...).
.  info A plain function name is parsed as defined(...).
.else
.  error
.endif

# A plain symbol name may start with one of the function names, in this case
# 'defined'.
.if defined-var
.  error
.else
# expect+1: Symbols may start with a function name.
.  info Symbols may start with a function name.
.endif

defined-var=	# defined but empty
.if defined-var
# expect+1: Symbols may start with a function name.
.  info Symbols may start with a function name.
.else
.  error
.endif

# expect+1: Missing closing parenthesis for defined()
.if defined(
.  error
.else
.  error
.endif