aboutsummaryrefslogtreecommitdiff
path: root/contrib/bmake/unit-tests/var-eval-short.mk
blob: 2b25d82e96b8e84e60248802bc2bd5afce4ea4de (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# $NetBSD: var-eval-short.mk,v 1.11 2023/10/19 18:24:33 rillig Exp $
#
# Tests for each variable modifier to ensure that they only do the minimum
# necessary computations.  If the result of the expression is irrelevant,
# the modifier should only be parsed.  The modifier should not be evaluated,
# but if it is evaluated for simplicity of the code (such as ':ts'), it must
# not have any observable side effects.
#
# See also:
#	var.c, the comment starting with 'The ApplyModifier functions'
#	ParseModifierPart, for evaluating nested expressions
#	cond-short.mk

FAIL=	${:!echo unexpected 1>&2!}

# The following tests only ensure that nested expressions are not evaluated.
# They cannot ensure that any unexpanded text returned from ParseModifierPart
# is ignored as well.  To do that, it is necessary to step through the code of
# each modifier.

# TODO: Test the modifiers in the same order as they occur in ApplyModifier.

.if 0 && ${FAIL}
.endif

.if 0 && ${VAR::=${FAIL}}
.elif defined(VAR)
.  error
.endif

.if 0 && ${${FAIL}:?then:else}
.endif

.if 0 && ${1:?${FAIL}:${FAIL}}
.endif

.if 0 && ${0:?${FAIL}:${FAIL}}
.endif

# Before var.c 1.870 from 2021-03-14, the expression ${FAIL} was evaluated
# after the loop, when undefining the temporary global loop variable.
# Since var.c 1.907 from 2021-04-04, a '$' is no longer allowed in the
# variable name.
# expect+2: In the :@ modifier of "", the variable name "${FAIL}" must not contain a dollar
# expect+1: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@})
.if 0 && ${:Uword:@${FAIL}@expr@}
.endif

.if 0 && ${:Uword:@var@${FAIL}@}
.endif

# Before var.c 1.877 from 2021-03-14, the modifier ':[...]' did not expand
# the nested expression ${FAIL} and then tried to parse the unexpanded text,
# which failed since '$' is not a valid range character.
.if 0 && ${:Uword:[${FAIL}]}
.endif

# Before var.c 1.867 from 2021-03-14, the modifier ':_' defined the variable
# even though the whole expression should have only been parsed, not
# evaluated.
.if 0 && ${:Uword:_=VAR}
.elif defined(VAR)
.  error
.endif

# Before var.c 1.856 from 2021-03-14, the modifier ':C' did not expand the
# nested expression ${FAIL}, which is correct, and then tried to compile the
# unexpanded text as a regular expression, which is unnecessary since the
# right-hand side of the '&&' cannot influence the outcome of the condition.
# Compiling the regular expression then failed both because of the '{FAIL}',
# which is not a valid repetition of the form '{1,5}', and because of the
# '****', which are repeated repetitions as well.
# '${FAIL}'
.if 0 && ${:Uword:C,${FAIL}****,,}
.endif

DEFINED=	# defined
.if 0 && ${DEFINED:D${FAIL}}
.endif

.if 0 && ${:Uword:E}
.endif

# Before var.c 1.1050 from 2023-05-09, the ':gmtime' modifier produced the
# error message 'Invalid time value: ${FAIL}}' since it did not expand its
# argument.
.if 0 && ${:Uword:gmtime=${FAIL}}
.endif

.if 0 && ${:Uword:H}
.endif

.if 0 && ${:Uword:hash}
.endif

.if 0 && ${value:L}
.endif

# Before var.c 1.1050 from 2023-05-09, the ':localtime' modifier produced the
# error message 'Invalid time value: ${FAIL}}' since it did not expand its
# argument.
.if 0 && ${:Uword:localtime=${FAIL}}
.endif

.if 0 && ${:Uword:M${FAIL}}
.endif

.if 0 && ${:Uword:N${FAIL}}
.endif

.if 0 && ${:Uword:O}
.endif

.if 0 && ${:Uword:Ox}
.endif

.if 0 && ${:Uword:P}
.endif

.if 0 && ${:Uword:Q}
.endif

.if 0 && ${:Uword:q}
.endif

.if 0 && ${:Uword:R}
.endif

.if 0 && ${:Uword:range}
.endif

.if 0 && ${:Uword:S,${FAIL},${FAIL},}
.endif

.if 0 && ${:Uword:sh}
.endif

.if 0 && ${:Uword:T}
.endif

.if 0 && ${:Uword:ts/}
.endif

.if 0 && ${:U${FAIL}}
.endif

.if 0 && ${:Uword:u}
.endif

.if 0 && ${:Uword:word=replacement}
.endif

# Before var.c 1.875 from 2021-03-14, Var_Parse returned "${FAIL}else" for the
# irrelevant right-hand side of the condition, even though this was not
# necessary.  Since the return value from Var_Parse is supposed to be ignored
# anyway, and since it is actually ignored in an overly complicated way,
# an empty string suffices.
.MAKEFLAGS: -dcpv
.if 0 && ${0:?${FAIL}then:${FAIL}else}
.endif

# The ':L' is applied before the ':?' modifier, giving the expression a name
# and a value, just to see whether this value gets passed through or whether
# the parse-only mode results in an empty string (only visible in the debug
# log).  As of var.c 1.875 from 2021-03-14, the value of the variable gets
# through, even though an empty string would suffice.
DEFINED=	defined
.if 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else}
.endif
.MAKEFLAGS: -d0

all: