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