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