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