1*dc1b8c9aSSimon J. Gerraty# $NetBSD: varmod-remember.mk,v 1.9 2023/02/09 22:21:57 rillig Exp $ 22c3632d1SSimon J. Gerraty# 3*dc1b8c9aSSimon J. Gerraty# Tests for the :_ modifier, which saves the current expression value 42c3632d1SSimon J. Gerraty# in the _ variable or another, to be used later again. 52c3632d1SSimon J. Gerraty 6*dc1b8c9aSSimon J. Gerraty 7*dc1b8c9aSSimon J. Gerraty# The ':_' modifier is typically used in situations where the value of an 8*dc1b8c9aSSimon J. Gerraty# expression is needed at the same time as a sequence of numbers. In these 9*dc1b8c9aSSimon J. Gerraty# cases, the value of the expression is saved in the temporary variable '_', 10*dc1b8c9aSSimon J. Gerraty# from where it is taken later in the same expression. 11*dc1b8c9aSSimon J. GerratyABC= ${A B C:L:_:range:@i@$i=${_:[$i]}@} 12*dc1b8c9aSSimon J. GerratyDEF= ${D E F:L:_:range:@i@$i=${_:[$i]}@} 13*dc1b8c9aSSimon J. GerratyGHI= ${G H I:L:_:range:@i@$i=${_:[$i]}@} 14*dc1b8c9aSSimon J. Gerraty 15*dc1b8c9aSSimon J. GerratyABC.global:= ${ABC} # is evaluated in the global scope 16*dc1b8c9aSSimon J. Gerraty.if ${ABC.global} != "1=A 2=B 3=C" 17b0c40a00SSimon J. Gerraty. error 18b0c40a00SSimon J. Gerraty.endif 19b0c40a00SSimon J. Gerraty 20*dc1b8c9aSSimon J. Gerraty.if ${DEF} != "1=D 2=E 3=F" # is evaluated in the command line scope 21*dc1b8c9aSSimon J. Gerraty. error 22*dc1b8c9aSSimon J. Gerraty.endif 23*dc1b8c9aSSimon J. Gerraty 24*dc1b8c9aSSimon J. Gerraty# Before var.c 1.1040 from 2023-02-09, the temporary variable '_' was placed 25*dc1b8c9aSSimon J. Gerraty# in the scope of the current evaluation, which meant that after the first 26*dc1b8c9aSSimon J. Gerraty# ':_' modifier had been evaluated in command line scope, all further 27*dc1b8c9aSSimon J. Gerraty# evaluations in global scope could not overwrite the variable '_' anymore, 28*dc1b8c9aSSimon J. Gerraty# as the command line scope takes precedence over the global scope. 29*dc1b8c9aSSimon J. Gerraty# The expression ${GHI} therefore evaluated to '1=D 2=E 3=F', reusing the 30*dc1b8c9aSSimon J. Gerraty# value of '_' from the previous evaluation in command line scope. 31*dc1b8c9aSSimon J. GerratyGHI.global:= ${GHI} # is evaluated in the global scope 32*dc1b8c9aSSimon J. Gerraty.if ${GHI.global} != "1=G 2=H 3=I" 33*dc1b8c9aSSimon J. Gerraty. error 34*dc1b8c9aSSimon J. Gerraty.endif 35*dc1b8c9aSSimon J. Gerraty 36*dc1b8c9aSSimon J. Gerraty 372c3632d1SSimon J. Gerraty# In the parameterized form, having the variable name on the right side of 38*dc1b8c9aSSimon J. Gerraty# the = assignment operator looks confusing. In almost all other situations, 39*dc1b8c9aSSimon J. Gerraty# the variable name is on the left-hand side of the = operator, therefore 40*dc1b8c9aSSimon J. Gerraty# '_=SAVED' looks like it would copy 'SAVED' to '_'. Luckily, this modifier 41*dc1b8c9aSSimon J. Gerraty# is only rarely needed. 42b0c40a00SSimon J. Gerraty.if ${1 2 3:L:@var@${var:_=SAVED:}@} != "1 2 3" 43b0c40a00SSimon J. Gerraty. error 44b0c40a00SSimon J. Gerraty.elif ${SAVED} != "3" 45b0c40a00SSimon J. Gerraty. error 46b0c40a00SSimon J. Gerraty.endif 47b0c40a00SSimon J. Gerraty 48*dc1b8c9aSSimon J. Gerraty 49*dc1b8c9aSSimon J. Gerraty# The ':_' modifier takes a variable name as optional argument. Before var.c 50*dc1b8c9aSSimon J. Gerraty# 1.867 from 2021-03-14, this variable name could refer to other variables, 51*dc1b8c9aSSimon J. Gerraty# such as in 'VAR.$p'. It was not possible to refer to 'VAR.${param}' though, 52*dc1b8c9aSSimon J. Gerraty# as that form caused a parse error. The cause for the parse error in 53*dc1b8c9aSSimon J. Gerraty# '${...:_=VAR.${param}}' is that the variable name is parsed in an ad-hoc 54*dc1b8c9aSSimon J. Gerraty# manner, stopping at the first ':', ')' or '}', without taking any nested 55*dc1b8c9aSSimon J. Gerraty# expressions into account. Due to this inconsistency that short expressions 56*dc1b8c9aSSimon J. Gerraty# are possible but long expressions aren't, the name of the temporary variable 57*dc1b8c9aSSimon J. Gerraty# is no longer expanded. 58b0c40a00SSimon J. Gerraty# 59*dc1b8c9aSSimon J. Gerraty# TODO: Warn about the unusual variable name '$S'. 60b0c40a00SSimon J. GerratyS= INDIRECT_VARNAME 61b0c40a00SSimon J. Gerraty.if ${value:L:@var@${var:_=$S}@} != "value" 62b0c40a00SSimon J. Gerraty. error 63b0c40a00SSimon J. Gerraty.elif defined(INDIRECT_VARNAME) 64b0c40a00SSimon J. Gerraty. error 65b0c40a00SSimon J. Gerraty.endif 66b0c40a00SSimon J. Gerraty 67*dc1b8c9aSSimon J. Gerraty 68*dc1b8c9aSSimon J. Gerraty# When a variable using ':_' refers to another variable that also uses ':_', 69*dc1b8c9aSSimon J. Gerraty# the value of the temporary variable '_' from the inner expression leaks into 70*dc1b8c9aSSimon J. Gerraty# the evaluation of the outer expression. If the expressions were evaluated 71*dc1b8c9aSSimon J. Gerraty# independently, the last word of the result would be outer_='outer' instead. 72*dc1b8c9aSSimon J. GerratyINNER= ${inner:L:_:@i@$i inner_='$_'@} 73*dc1b8c9aSSimon J. GerratyOUTER= ${outer:L:_:@o@$o ${INNER} outer_='$_'@} 74*dc1b8c9aSSimon J. Gerraty.if ${OUTER} != "outer inner inner_='inner' outer_='inner'" 75*dc1b8c9aSSimon J. Gerraty.endif 76*dc1b8c9aSSimon J. Gerraty 77*dc1b8c9aSSimon J. Gerraty 782c3632d1SSimon J. Gerratyall: 79