1 # $NetBSD: varmisc.mk,v 1.38 2025/06/28 22:39:29 rillig 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 cmpv 7 all: save-dollars 8 all: export-appended 9 all: parse-dynamic 10 all: varerror-unclosed-{1,2,3,4,5,6,7,8} 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 # big jumps to handle 3 digits per step 50 M_cmpv.units= 1 1000 1000000 51 M_cmpv= S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh 52 53 Version= 123.456.789 54 cmpv.only= target specific vars 55 56 cmpv: 57 @echo Version=${Version} == ${Version:${M_cmpv}} 58 @echo Literal=3.4.5 == ${3.4.5:L:${M_cmpv}} 59 @echo We have ${${.TARGET:T}.only} 60 61 62 # Test parsing of boolean values. 63 # begin .MAKE.SAVE_DOLLARS; see Var_SetWithFlags and ParseBoolean. 64 SD_VALUES= 0 1 2 False True false true Yes No yes no On Off ON OFF on off 65 SD_4_DOLLARS= $$$$ 66 67 .for val in ${SD_VALUES} 68 # The assignment must be done using ':=' since a simple '=' would be 69 # interpreted as 'yes', due to the leading '$'; see ParseBoolean. 70 .MAKE.SAVE_DOLLARS:= ${val} 71 SD.${val}:= ${SD_4_DOLLARS} 72 .endfor 73 .MAKE.SAVE_DOLLARS:= yes 74 75 save-dollars: 76 .for val in ${SD_VALUES} 77 @printf '%s: %-8s = %s\n' $@ ${val} ${SD.${val}:Q} 78 .endfor 79 # end .MAKE.SAVE_DOLLARS 80 81 # Appending to an undefined variable does not add a space in front. 82 .undef APPENDED 83 APPENDED+= value 84 .if ${APPENDED} != "value" 85 . error "${APPENDED}" 86 .endif 87 88 # Appending to an empty variable adds a space between the old value 89 # and the additional value. 90 APPENDED= # empty 91 APPENDED+= value 92 .if ${APPENDED} != " value" 93 . error "${APPENDED}" 94 .endif 95 96 # Appending to parameterized variables works as well. 97 PARAM= param 98 VAR.${PARAM}= 1 99 VAR.${PARAM}+= 2 100 .if ${VAR.param} != "1 2" 101 . error "${VAR.param}" 102 .endif 103 104 # The variable name can contain arbitrary characters. 105 # If the expanded variable name ends in a +, this still does not influence 106 # the parser. The assignment operator is still a simple assignment. 107 # Therefore, there is no need to add a space between the variable name 108 # and the assignment operator. 109 PARAM= + 110 VAR.${PARAM}= 1 111 VAR.${PARAM}+= 2 112 .if ${VAR.+} != "1 2" 113 . error "${VAR.+}" 114 .endif 115 .for param in : + ! ? 116 VAR.${param}= ${param} 117 .endfor 118 .if ${VAR.${:U\:}} != ":" || ${VAR.+} != "+" || ${VAR.!} != "!" || ${VAR.?} != "?" 119 . error "${VAR.+}" "${VAR.!}" "${VAR.?}" 120 .endif 121 122 # Appending to a variable from the environment creates a copy of that variable 123 # in the global scope. 124 # The appended value is not exported automatically. 125 # When a variable is exported, the exported value is taken at the time of the 126 # .export directive. Later changes to the variable have no effect. 127 .export FROM_ENV_BEFORE 128 FROM_ENV+= mk 129 FROM_ENV_BEFORE+= mk 130 FROM_ENV_AFTER+= mk 131 .export FROM_ENV_AFTER 132 133 export-appended: 134 @echo $@: "$$FROM_ENV" 135 @echo $@: "$$FROM_ENV_BEFORE" 136 @echo $@: "$$FROM_ENV_AFTER" 137 138 # begin parse-dynamic 139 # 140 # Demonstrate that the target-specific variables are not evaluated in 141 # the global scope. Their expressions are preserved until there is a local 142 # scope in which resolving them makes sense. 143 144 # There are different code paths for short names ... 145 ${:U>}= before 146 GS_TARGET:= $@ 147 GS_MEMBER:= $% 148 GS_PREFIX:= $* 149 GS_ARCHIVE:= $! 150 GS_ALLSRC:= $> 151 ${:U>}= after 152 # ... and for braced short names ... 153 GB_TARGET:= ${@} 154 GB_MEMBER:= ${%} 155 GB_PREFIX:= ${*} 156 GB_ARCHIVE:= ${!} 157 GB_ALLSRC:= ${>} 158 # ... and for long names. 159 GL_TARGET:= ${.TARGET} 160 GL_MEMBER:= ${.MEMBER} 161 GL_PREFIX:= ${.PREFIX} 162 GL_ARCHIVE:= ${.ARCHIVE} 163 GL_ALLSRC:= ${.ALLSRC} 164 165 parse-dynamic: 166 @echo $@: ${GS_TARGET} ${GS_MEMBER} ${GS_PREFIX} ${GS_ARCHIVE} ${GS_ALLSRC} 167 @echo $@: ${GB_TARGET} ${GB_MEMBER} ${GB_PREFIX} ${GB_ARCHIVE} ${GB_ALLSRC} 168 @echo $@: ${GL_TARGET} ${GL_MEMBER} ${GL_PREFIX} ${GL_ARCHIVE} ${GL_ALLSRC} 169 170 # Since 2020-07-28, make complains about unclosed variables. 171 # Before that, it had complained about unclosed variables only when 172 # parsing the modifiers, but not when parsing the variable name. 173 174 UNCLOSED_INDIR_1= ${UNCLOSED_ORIG 175 UNCLOSED_INDIR_2= ${UNCLOSED_INDIR_1} 176 177 FLAGS= one two 178 FLAGS+= ${FLAGS.${.ALLSRC:M*.c:T:u}} 179 FLAGS.target2.c= three four 180 181 target1.c: 182 target2.c: 183 184 all: target1-flags target2-flags 185 target1-flags: target1.c 186 @echo $@: we have: ${FLAGS} 187 188 target2-flags: target2.c 189 @echo $@: we have: ${FLAGS} 190 191 varerror-unclosed-1: 192 @echo $@:begin 193 varerror-unclosed-2: 194 # expect: make: Unclosed variable "" 195 @echo $( 196 varerror-unclosed-3: 197 # expect: make: Unclosed variable "UNCLOSED" 198 @echo $(UNCLOSED 199 varerror-unclosed-4: 200 # expect: make: Unclosed variable "UNCLOSED" 201 @echo ${UNCLOSED 202 varerror-unclosed-5: 203 # expect: make: Unclosed expression, expecting "}" for modifier "M${PATTERN" 204 @echo ${UNCLOSED:M${PATTERN 205 varerror-unclosed-6: 206 # expect: make: Unclosed variable "param" 207 # expect: make: Unclosed variable "UNCLOSED." 208 @echo ${UNCLOSED.${param 209 varerror-unclosed-7: 210 @echo $ 211 .for i in 1 2 3 212 # expect: make: Unclosed variable "UNCLOSED.1" 213 @echo ${UNCLOSED.${i} 214 .endfor 215 varerror-unclosed-8: 216 @echo ${UNCLOSED_INDIR_2} 217 @echo $@:end 218