xref: /freebsd/contrib/bmake/unit-tests/var-eval-short.mk (revision 397e83df75e0fcd0d3fcb95ae4d794cb7600fc89)
1# $NetBSD: var-eval-short.mk,v 1.12 2024/04/20 10:18:55 rillig Exp $
2#
3# Tests for each variable modifier to ensure that they only do the minimum
4# necessary computations.  If the result of the expression is irrelevant,
5# the modifier should only be parsed.  The modifier should not be evaluated,
6# but if it is evaluated for simplicity of the code (such as ':ts'), it must
7# not have any observable side effects.
8#
9# See also:
10#	var.c, the comment starting with 'The ApplyModifier functions'
11#	ParseModifierPart, for evaluating nested expressions
12#	cond-short.mk
13
14FAIL=	${:!echo unexpected 1>&2!}
15
16# The following tests only ensure that nested expressions are not evaluated.
17# They cannot ensure that any unexpanded text returned from ParseModifierPart
18# is ignored as well.  To do that, it is necessary to step through the code of
19# each modifier.
20
21# TODO: Test the modifiers in the same order as they occur in ApplyModifier.
22
23.if 0 && ${FAIL}
24.endif
25
26.if 0 && ${VAR::=${FAIL}}
27.elif defined(VAR)
28.  error
29.endif
30
31.if 0 && ${${FAIL}:?then:else}
32.endif
33
34.if 0 && ${1:?${FAIL}:${FAIL}}
35.endif
36
37.if 0 && ${0:?${FAIL}:${FAIL}}
38.endif
39
40# Before var.c 1.870 from 2021-03-14, the expression ${FAIL} was evaluated
41# after the loop, when undefining the temporary global loop variable.
42# Since var.c 1.907 from 2021-04-04, a '$' is no longer allowed in the
43# variable name.
44# expect+2: while evaluating "${:Uword:@${FAIL}@expr@}": In the :@ modifier, the variable name "${FAIL}" must not contain a dollar
45# expect+1: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@})
46.if 0 && ${:Uword:@${FAIL}@expr@}
47.endif
48
49.if 0 && ${:Uword:@var@${FAIL}@}
50.endif
51
52# Before var.c 1.877 from 2021-03-14, the modifier ':[...]' did not expand
53# the nested expression ${FAIL} and then tried to parse the unexpanded text,
54# which failed since '$' is not a valid range character.
55.if 0 && ${:Uword:[${FAIL}]}
56.endif
57
58# Before var.c 1.867 from 2021-03-14, the modifier ':_' defined the variable
59# even though the whole expression should have only been parsed, not
60# evaluated.
61.if 0 && ${:Uword:_=VAR}
62.elif defined(VAR)
63.  error
64.endif
65
66# Before var.c 1.856 from 2021-03-14, the modifier ':C' did not expand the
67# nested expression ${FAIL}, which is correct, and then tried to compile the
68# unexpanded text as a regular expression, which is unnecessary since the
69# right-hand side of the '&&' cannot influence the outcome of the condition.
70# Compiling the regular expression then failed both because of the '{FAIL}',
71# which is not a valid repetition of the form '{1,5}', and because of the
72# '****', which are repeated repetitions as well.
73# '${FAIL}'
74.if 0 && ${:Uword:C,${FAIL}****,,}
75.endif
76
77DEFINED=	# defined
78.if 0 && ${DEFINED:D${FAIL}}
79.endif
80
81.if 0 && ${:Uword:E}
82.endif
83
84# Before var.c 1.1050 from 2023-05-09, the ':gmtime' modifier produced the
85# error message 'Invalid time value: ${FAIL}}' since it did not expand its
86# argument.
87.if 0 && ${:Uword:gmtime=${FAIL}}
88.endif
89
90.if 0 && ${:Uword:H}
91.endif
92
93.if 0 && ${:Uword:hash}
94.endif
95
96.if 0 && ${value:L}
97.endif
98
99# Before var.c 1.1050 from 2023-05-09, the ':localtime' modifier produced the
100# error message 'Invalid time value: ${FAIL}}' since it did not expand its
101# argument.
102.if 0 && ${:Uword:localtime=${FAIL}}
103.endif
104
105.if 0 && ${:Uword:M${FAIL}}
106.endif
107
108.if 0 && ${:Uword:N${FAIL}}
109.endif
110
111.if 0 && ${:Uword:O}
112.endif
113
114.if 0 && ${:Uword:Ox}
115.endif
116
117.if 0 && ${:Uword:P}
118.endif
119
120.if 0 && ${:Uword:Q}
121.endif
122
123.if 0 && ${:Uword:q}
124.endif
125
126.if 0 && ${:Uword:R}
127.endif
128
129.if 0 && ${:Uword:range}
130.endif
131
132.if 0 && ${:Uword:S,${FAIL},${FAIL},}
133.endif
134
135.if 0 && ${:Uword:sh}
136.endif
137
138.if 0 && ${:Uword:T}
139.endif
140
141.if 0 && ${:Uword:ts/}
142.endif
143
144.if 0 && ${:U${FAIL}}
145.endif
146
147.if 0 && ${:Uword:u}
148.endif
149
150.if 0 && ${:Uword:word=replacement}
151.endif
152
153# Before var.c 1.875 from 2021-03-14, Var_Parse returned "${FAIL}else" for the
154# irrelevant right-hand side of the condition, even though this was not
155# necessary.  Since the return value from Var_Parse is supposed to be ignored
156# anyway, and since it is actually ignored in an overly complicated way,
157# an empty string suffices.
158.MAKEFLAGS: -dcpv
159.if 0 && ${0:?${FAIL}then:${FAIL}else}
160.endif
161
162# The ':L' is applied before the ':?' modifier, giving the expression a name
163# and a value, just to see whether this value gets passed through or whether
164# the parse-only mode results in an empty string (only visible in the debug
165# log).  As of var.c 1.875 from 2021-03-14, the value of the variable gets
166# through, even though an empty string would suffice.
167DEFINED=	defined
168.if 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else}
169.endif
170.MAKEFLAGS: -d0
171
172all:
173