var-eval-short.mk revision 1.15 1 # $NetBSD: var-eval-short.mk,v 1.15 2024/08/06 18:00:17 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
14 FAIL= ${:!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 parsing "${: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
77 DEFINED= # 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.
167 DEFINED= defined
168 .if 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else}
169 .endif
170 .MAKEFLAGS: -d0
171
172 all:
173