diff options
| author | rillig <rillig@NetBSD.org> | 2023-07-01 09:06:34 +0000 |
|---|---|---|
| committer | rillig <rillig@NetBSD.org> | 2023-07-01 09:06:34 +0000 |
| commit | 8d9b395b7b8c2aa17b26c54a76a76eb0093ee374 (patch) | |
| tree | c21429df9560a0da3c2d1bd2df76fa837552176f /usr.bin | |
| parent | 46afb07be619aa3e407988421de1e83a3248f207 (diff) | |
tests/make: show how to use indirect conditions in the '?:' modifier
Diffstat (limited to 'usr.bin')
| -rw-r--r-- | usr.bin/make/unit-tests/varmod-ifelse.exp | 26 | ||||
| -rw-r--r-- | usr.bin/make/unit-tests/varmod-ifelse.mk | 54 |
2 files changed, 63 insertions, 17 deletions
diff --git a/usr.bin/make/unit-tests/varmod-ifelse.exp b/usr.bin/make/unit-tests/varmod-ifelse.exp index 5b83ed49a75..413f0b9ba4d 100644 --- a/usr.bin/make/unit-tests/varmod-ifelse.exp +++ b/usr.bin/make/unit-tests/varmod-ifelse.exp @@ -16,17 +16,17 @@ CondParser_Eval: ${VAR} == value Comparing "value" == "value" Comparing "ok" != "ok" make: "varmod-ifelse.mk" line 158: no. -make: "varmod-ifelse.mk" line 161: Comparison with '>=' requires both operands 'no' and '10' to be numeric +make: "varmod-ifelse.mk" line 162: Comparison with '>=' requires both operands 'no' and '10' to be numeric make: Bad conditional expression 'string == "literal" || no >= 10' in 'string == "literal" || no >= 10?yes:no' -make: "varmod-ifelse.mk" line 161: . +make: "varmod-ifelse.mk" line 162: . make: Bad conditional expression 'string == "literal" && >= 10' in 'string == "literal" && >= 10?yes:no' -make: "varmod-ifelse.mk" line 167: . -make: Bad conditional expression 'string == "literal" || >= 10' in 'string == "literal" || >= 10?yes:no' make: "varmod-ifelse.mk" line 169: . -make: "varmod-ifelse.mk" line 177: true -make: "varmod-ifelse.mk" line 180: false +make: Bad conditional expression 'string == "literal" || >= 10' in 'string == "literal" || >= 10?yes:no' +make: "varmod-ifelse.mk" line 172: . +make: "varmod-ifelse.mk" line 180: <true> +make: "varmod-ifelse.mk" line 183: <false> make: Bad conditional expression ' ' in ' ?true:false' -make: "varmod-ifelse.mk" line 182: +make: "varmod-ifelse.mk" line 186: <> CondParser_Eval: 0 && ${1:?${:Uthen0:S,}},,}:${:Uelse0:S,}},,}} != "not evaluated" CondParser_Eval: 1 && ${0:?${:Uthen1:S,}},,}:${:Uelse1:S,}},,}} != "else1" CondParser_Eval: 0 @@ -34,6 +34,18 @@ Comparing "else1" != "else1" CondParser_Eval: 2 && ${1:?${:Uthen2:S,}},,}:${:Uelse2:S,}},,}} != "then2" CondParser_Eval: 1 Comparing "then2" != "then2" +CondParser_Eval: ${DELAYED} == "one" +Comparing "two" == "one" +make: "varmod-ifelse.mk" line 282: no +CondParser_Eval: ${DELAYED} == "two" +Comparing "two" == "two" +make: "varmod-ifelse.mk" line 284: yes +CondParser_Eval: ${DELAYED} == "one" +Comparing "two" == "one" +make: "varmod-ifelse.mk" line 287: no +CondParser_Eval: ${DELAYED} == "two" +Comparing "two" == "two" +make: "varmod-ifelse.mk" line 290: yes make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/usr.bin/make/unit-tests/varmod-ifelse.mk b/usr.bin/make/unit-tests/varmod-ifelse.mk index 1a71cab5c7a..62d3333b71a 100644 --- a/usr.bin/make/unit-tests/varmod-ifelse.mk +++ b/usr.bin/make/unit-tests/varmod-ifelse.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-ifelse.mk,v 1.22 2023/06/01 20:56:35 rillig Exp $ +# $NetBSD: varmod-ifelse.mk,v 1.23 2023/07/01 09:06:34 rillig Exp $ # # Tests for the ${cond:?then:else} variable modifier, which evaluates either # the then-expression or the else-expression, depending on the condition. @@ -97,11 +97,11 @@ COND:= ${${UNDEF} == "":?bad-assign:bad-assign} .endif .MAKEFLAGS: -d0 -# As of 2020-12-10, the variable "name" is first expanded, and the result of +# As of 2020-12-10, the variable "VAR" is first expanded, and the result of # this expansion is then taken as the condition. To force the variable # expression in the condition to be evaluated at exactly the right point, # the '$' of the intended '${VAR}' escapes from the parser in form of the -# expression ${:U\$}. Because of this escaping, the variable "name" and thus +# expression ${:U\$}. Because of this escaping, the variable "VAR" and thus # the condition ends up as "${VAR} == value", just as intended. # # This hack does not work for variables from .for loops since these are @@ -156,15 +156,18 @@ STRING= string NUMBER= no # not really a number # expect+1: no. .info ${${STRING} == "literal" && ${NUMBER} >= 10:?yes:no}. -# expect+2: . -# expect+1: Comparison with '>=' requires both operands 'no' and '10' to be numeric +# expect+3: Comparison with '>=' requires both operands 'no' and '10' to be numeric +# expect: make: Bad conditional expression 'string == "literal" || no >= 10' in 'string == "literal" || no >= 10?yes:no' +# expect+1: . .info ${${STRING} == "literal" || ${NUMBER} >= 10:?yes:no}. # The following situation occasionally occurs with MKINET6 or similar # variables. NUMBER= # empty, not really a number either +# expect: make: Bad conditional expression 'string == "literal" && >= 10' in 'string == "literal" && >= 10?yes:no' # expect+1: . .info ${${STRING} == "literal" && ${NUMBER} >= 10:?yes:no}. +# expect: make: Bad conditional expression 'string == "literal" || >= 10' in 'string == "literal" || >= 10?yes:no' # expect+1: . .info ${${STRING} == "literal" || ${NUMBER} >= 10:?yes:no}. @@ -173,13 +176,14 @@ PLUS= + ASTERISK= * EMPTY= # empty # "true" since "+" is not the empty string. -# expect+1: true -.info ${${PLUS} :?true:false} +# expect+1: <true> +.info <${${PLUS} :?true:false}> # "false" since the variable named "*" is not defined. -# expect+1: false -.info ${${ASTERISK} :?true:false} +# expect+1: <false> +.info <${${ASTERISK} :?true:false}> # syntax error since the condition is completely blank. -.info ${${EMPTY} :?true:false} +# expect+1: <> +.info <${${EMPTY} :?true:false}> # Since the condition of the '?:' modifier is expanded before being parsed and @@ -256,4 +260,34 @@ PRIMES= 2 3 5 7 11 # with the 'then2' formed the result 'then2,,}}'. . error .endif + + +# Since the condition is taken from the variable name of the expression, not +# from its value, it is evaluated early. It is possible though to construct +# conditions that are evaluated lazily, at exactly the right point. There is +# no way to escape a '$' directly in the variable name, but there are +# alternative ways to bring a '$' into the condition. +# +# In an indirect condition using the ':U' modifier, each '$', ':' and +# '}' must be escaped as '\$', '\:' and '\}', respectively, but '{' must +# not be escaped. +# +# In an indirect condition using a separate variable, each '$' must be +# escaped as '$$'. +# +# These two forms allow the variables to contain arbitrary characters, as the +# condition parser does not see them. +DELAYED= two +# expect+1: no +.info ${ ${:U \${DELAYED\} == "one"}:?yes:no} +# expect+1: yes +.info ${ ${:U \${DELAYED\} == "two"}:?yes:no} +INDIRECT_COND1= $${DELAYED} == "one" +# expect+1: no +.info ${ ${INDIRECT_COND1}:?yes:no} +INDIRECT_COND2= $${DELAYED} == "two" +# expect+1: yes +.info ${ ${INDIRECT_COND2}:?yes:no} + + .MAKEFLAGS: -d0 |
