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