]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bmake/unit-tests/varmisc.mk
Merge bmake-20201117
[FreeBSD/FreeBSD.git] / contrib / bmake / unit-tests / varmisc.mk
1 # $Id: varmisc.mk,v 1.21 2020/11/11 23:08:50 sjg Exp $
2 # $NetBSD: varmisc.mk,v 1.28 2020/11/07 00:07:02 rillig Exp $
3 #
4 # Miscellaneous variable tests.
5
6 all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none \
7         strftime cmpv manok
8 all: save-dollars
9 all: export-appended
10 all: parse-dynamic
11 all: varerror-unclosed
12
13 unmatched_var_paren:
14         @echo ${foo::=foo-text}
15
16 True=   ${echo true >&2:L:sh}TRUE
17 False=  ${echo false >&2:L:sh}FALSE
18
19 VSET=   is set
20 .undef UNDEF
21
22 U_false:
23         @echo :U skipped when var set
24         @echo ${VSET:U${False}}
25
26 D_false:
27         @echo :D skipped if var undef
28         @echo ${UNDEF:D${False}}
29
30 U_true:
31         @echo :U expanded when var undef
32         @echo ${UNDEF:U${True}}
33
34 D_true:
35         @echo :D expanded when var set
36         @echo ${VSET:D${True}}
37
38 Q_lhs:
39         @echo :? only lhs when value true
40         @echo ${1:L:?${True}:${False}}
41
42 Q_rhs:
43         @echo :? only rhs when value false
44         @echo ${0:L:?${True}:${False}}
45
46 NQ_none:
47         @echo do not evaluate or expand :? if discarding
48         @echo ${VSET:U${1:L:?${True}:${False}}}
49
50 April1= 1459494000
51
52 # slightly contorted syntax to use utc via variable
53 strftime:
54         @echo ${year=%Y month=%m day=%d:L:gmtime=1459494000}
55         @echo date=${%Y%m%d:L:${gmtime=${April1}:L}}
56
57 # big jumps to handle 3 digits per step
58 M_cmpv.units=   1 1000 1000000
59 M_cmpv=         S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
60
61 Version=        123.456.789
62 cmpv.only=      target specific vars
63
64 cmpv:
65         @echo Version=${Version} == ${Version:${M_cmpv}}
66         @echo Literal=3.4.5 == ${3.4.5:L:${M_cmpv}}
67         @echo We have ${${.TARGET:T}.only}
68
69 # catch misshandling of nested vars in .for loop
70 MAN=
71 MAN1=   make.1
72 .for s in 1 2
73 .  if defined(MAN$s) && !empty(MAN$s)
74 MAN+=   ${MAN$s}
75 .  endif
76 .endfor
77
78 manok:
79         @echo MAN=${MAN}
80
81 # This is an expanded variant of the above .for loop.
82 # Between 2020-06-28 and 2020-07-02 this paragraph generated a wrong
83 # error message "Variable VARNAME is recursive".
84 # When evaluating the !empty expression, the ${:U1} was not expanded and
85 # thus resulted in the seeming definition VARNAME=${VARNAME}, which is
86 # obviously recursive.
87 VARNAME=        ${VARNAME${:U1}}
88 .if defined(VARNAME${:U2}) && !empty(VARNAME${:U2})
89 .endif
90
91 # begin .MAKE.SAVE_DOLLARS; see Var_SetWithFlags and ParseBoolean.
92 SD_VALUES=      0 1 2 False True false true Yes No yes no On Off ON OFF on off
93 SD_4_DOLLARS=   $$$$
94
95 .for val in ${SD_VALUES}
96 .MAKE.SAVE_DOLLARS:=    ${val}  # Must be := since a simple = has no effect.
97 SD.${val}:=             ${SD_4_DOLLARS}
98 .endfor
99 .MAKE.SAVE_DOLLARS:=    yes
100
101 save-dollars:
102 .for val in ${SD_VALUES}
103         @printf '%s: %-8s = %s\n' $@ ${val} ${SD.${val}:Q}
104 .endfor
105
106 # Appending to an undefined variable does not add a space in front.
107 .undef APPENDED
108 APPENDED+=      value
109 .if ${APPENDED} != "value"
110 .  error "${APPENDED}"
111 .endif
112
113 # Appending to an empty variable adds a space between the old value
114 # and the additional value.
115 APPENDED=       # empty
116 APPENDED+=      value
117 .if ${APPENDED} != " value"
118 .  error "${APPENDED}"
119 .endif
120
121 # Appending to parameterized variables works as well.
122 PARAM=          param
123 VAR.${PARAM}=   1
124 VAR.${PARAM}+=  2
125 .if ${VAR.param} != "1 2"
126 .  error "${VAR.param}"
127 .endif
128
129 # The variable name can contain arbitrary characters.
130 # If the expanded variable name ends in a +, this still does not influence
131 # the parser. The assignment operator is still a simple assignment.
132 # Therefore, there is no need to add a space between the variable name
133 # and the assignment operator.
134 PARAM=          +
135 VAR.${PARAM}=   1
136 VAR.${PARAM}+=  2
137 .if ${VAR.+} != "1 2"
138 .  error "${VAR.+}"
139 .endif
140 .for param in + ! ?
141 VAR.${param}=   ${param}
142 .endfor
143 .if ${VAR.+} != "+" || ${VAR.!} != "!" || ${VAR.?} != "?"
144 .  error "${VAR.+}" "${VAR.!}" "${VAR.?}"
145 .endif
146
147 # Appending to a variable from the environment creates a copy of that variable
148 # in the global context.
149 # The appended value is not exported automatically.
150 # When a variable is exported, the exported value is taken at the time of the
151 # .export directive. Later changes to the variable have no effect.
152 .export FROM_ENV_BEFORE
153 FROM_ENV+=              mk
154 FROM_ENV_BEFORE+=       mk
155 FROM_ENV_AFTER+=        mk
156 .export FROM_ENV_AFTER
157
158 export-appended:
159         @echo $@: "$$FROM_ENV"
160         @echo $@: "$$FROM_ENV_BEFORE"
161         @echo $@: "$$FROM_ENV_AFTER"
162
163 # begin parse-dynamic
164 #
165 # Demonstrate that the target-specific variables are not evaluated in
166 # the global context. They are preserved until there is a local context
167 # in which resolving them makes sense.
168
169 # There are different code paths for short names ...
170 ${:U>}=         before
171 GS_TARGET:=     $@
172 GS_MEMBER:=     $%
173 GS_PREFIX:=     $*
174 GS_ARCHIVE:=    $!
175 GS_ALLSRC:=     $>
176 ${:U>}=         after
177 # ... and for braced short names ...
178 GB_TARGET:=     ${@}
179 GB_MEMBER:=     ${%}
180 GB_PREFIX:=     ${*}
181 GB_ARCHIVE:=    ${!}
182 GB_ALLSRC:=     ${>}
183 # ... and for long names.
184 GL_TARGET:=     ${.TARGET}
185 GL_MEMBER:=     ${.MEMBER}
186 GL_PREFIX:=     ${.PREFIX}
187 GL_ARCHIVE:=    ${.ARCHIVE}
188 GL_ALLSRC:=     ${.ALLSRC}
189
190 parse-dynamic:
191         @echo $@: ${GS_TARGET} ${GS_MEMBER} ${GS_PREFIX} ${GS_ARCHIVE} ${GS_ALLSRC}
192         @echo $@: ${GB_TARGET} ${GB_MEMBER} ${GB_PREFIX} ${GB_ARCHIVE} ${GB_ALLSRC}
193         @echo $@: ${GL_TARGET} ${GL_MEMBER} ${GL_PREFIX} ${GL_ARCHIVE} ${GL_ALLSRC}
194
195 # Since 2020-07-28, make complains about unclosed variables.
196 # Before that, it had complained about unclosed variables only when
197 # parsing the modifiers, but not when parsing the variable name.
198
199 UNCLOSED_INDIR_1=       ${UNCLOSED_ORIG
200 UNCLOSED_INDIR_2=       ${UNCLOSED_INDIR_1}
201
202 FLAGS=  one two
203 FLAGS+= ${FLAGS.${.ALLSRC:M*.c:T:u}}
204 FLAGS.target2.c= three four
205
206 target1.c:
207 target2.c:
208
209 all: target1-flags target2-flags
210 target1-flags: target1.c
211         @echo $@: we have: ${FLAGS}
212
213 target2-flags: target2.c
214         @echo $@: we have: ${FLAGS}
215
216 varerror-unclosed:
217         @echo $@:begin
218         @echo $(
219         @echo $(UNCLOSED
220         @echo ${UNCLOSED
221         @echo ${UNCLOSED:M${PATTERN
222         @echo ${UNCLOSED.${param
223         @echo $
224 .for i in 1 2 3
225         @echo ${UNCLOSED.${i}
226 .endfor
227         @echo ${UNCLOSED_INDIR_2}
228         @echo $@:end