Home | History | Annotate | Line # | Download | only in unit-tests
varmisc.mk revision 1.26
      1 # $NetBSD: varmisc.mk,v 1.26 2020/10/24 08:50:17 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 	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
    228