Home | History | Annotate | Line # | Download | only in unit-tests
      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