cond-func-empty.mk (bmake-20201101) | : | cond-func-empty.mk (bmake-20201117) | ||
---|---|---|---|---|
# $NetBSD: cond-func-empty.mk,v 1.8 2020/09/23 08:11:28 rillig Exp $ | # $NetBSD: cond-func-empty.mk,v 1.10 2020/11/15 14:07:53 rillig Exp $ | |||
# | # | |||
# Tests for the empty() function in .if conditions, which tests a variable | # Tests for the empty() function in .if conditions, which tests a variable | |||
# expression for emptiness. | # expression for emptiness. | |||
# | # | |||
# Note that the argument in the parentheses is indeed a variable name, | # Note that the argument in the parentheses is indeed a variable name, | |||
# optionally followed by variable modifiers. This is like the defined() | # optionally followed by variable modifiers. | |||
# function. | ||||
# | # | |||
.undef UNDEF | .undef UNDEF | |||
EMPTY= # empty | EMPTY= # empty | |||
SPACE= ${:U } | SPACE= ${:U } | |||
WORD= word | WORD= word | |||
# An undefined variable is empty. | # An undefined variable is empty. | |||
.if !empty(UNDEF) | .if !empty(UNDEF) | |||
. error | . error | |||
.endif | .endif | |||
# An undefined variable has the empty string as the value, and the :M | # An undefined variable has the empty string as the value, and the :M | |||
# variable modifier does not change that. | # variable modifier does not change that. | |||
# | # | |||
.if !empty(UNDEF:M*) | .if !empty(UNDEF:M*) | |||
. error | . error | |||
.endif | .endif | |||
# The :S modifier replaces the empty value with an actual word, and | # The :S modifier replaces the empty value with an actual word. The | |||
# after that the expression is no longer empty. Because the variable | # expression is now no longer empty, but it is still possible to see whether | |||
# was undefined in the first place, the expression has the flag VAR_JUNK | # the expression was based on an undefined variable. The expression has the | |||
# but not VAR_KEEP, therefore it is still considered undefined. | # flag VEF_UNDEF. | |||
# Only very few variable modifiers turn an undefined variable expression | # | |||
# into a defined variable expression. The :U and :D modifiers belong to | # The expression does not have the flag VEF_DEF though, therefore it is still | |||
# that group, but :S doesn't (see VAR_KEEP). | # considered undefined. Yes, indeed, undefined but not empty. There are a | |||
# few variable modifiers that turn an undefined expression into a defined | ||||
# expression, among them :U and :D, but not :S. | ||||
# | # | |||
# XXX: This is hard to explain to someone who doesn't know these | # XXX: This is hard to explain to someone who doesn't know these | |||
# implementation details. | # implementation details. | |||
# | # | |||
.if !empty(UNDEF:S,^$,value,W) | .if !empty(UNDEF:S,^$,value,W) | |||
. error | . error | |||
.endif | .endif | |||
# The :U modifier modifies expressions based on undefined variables | # The :U modifier modifies expressions based on undefined variables | |||
# (VAR_JUNK) by adding the VAR_KEEP flag, which marks the expression | # (VAR_JUNK) by adding the VAR_KEEP flag, which marks the expression | |||
# as "being interesting enough to be further processed". | # as "being interesting enough to be further processed". | |||
# | # | |||
.if empty(UNDEF:S,^$,value,W:Ufallback) | .if empty(UNDEF:S,^$,value,W:Ufallback) | |||
. error | . error | |||
.endif | .endif | |||
# And now to the surprising part. Applying the following :S modifier to the | # And now to the surprising part. Applying the following :S modifier to the | |||
# undefined variable makes it non-empty, but the marker VAR_JUNK is preserved | # undefined expression makes it non-empty, but the marker VEF_UNDEF is | |||
# nevertheless. The :U modifier that follows only looks at VAR_JUNK to decide | # preserved nevertheless. The :U modifier that follows only looks at the | |||
# whether the variable is defined or not. This kind of makes sense since the | # VEF_UNDEF flag to decide whether the variable is defined or not. This kind | |||
# :U modifier tests the _variable_, not the _expression_. | # of makes sense since the :U modifier tests the _variable_, not the | |||
# _expression_. | ||||
# | # | |||
# But since the variable was undefined to begin with, the fallback value is | # But since the variable was undefined to begin with, the fallback value from | |||
# used in this expression. | # the :U modifier is used in this expression. | |||
# | # | |||
.if ${UNDEF:S,^$,value,W:Ufallback} != "fallback" | .if ${UNDEF:S,^$,value,W:Ufallback} != "fallback" | |||
. error | . error | |||
.endif | .endif | |||
# The variable EMPTY is completely empty (0 characters). | # The variable EMPTY is completely empty (0 characters). | |||
.if !empty(EMPTY) | .if !empty(EMPTY) | |||
. error | . error | |||
.endif | .endif | |||
skipping to change at line 131 | skipping to change at line 133 | |||
. error | . error | |||
.endif | .endif | |||
# Ensure that variable expressions that appear as part of the argument are | # Ensure that variable expressions that appear as part of the argument are | |||
# properly parsed. Typical use cases for this are .for loops, which are | # properly parsed. Typical use cases for this are .for loops, which are | |||
# expanded to exactly these ${:U} expressions. | # expanded to exactly these ${:U} expressions. | |||
# | # | |||
# If everything goes well, the argument expands to "WORD", and that variable | # If everything goes well, the argument expands to "WORD", and that variable | |||
# is defined at the beginning of this file. The surrounding 'W' and 'D' | # is defined at the beginning of this file. The surrounding 'W' and 'D' | |||
# ensure that the parser in ParseEmptyArg has the correct position, both | # ensure that the parser in ParseEmptyArg has the correct position, both | |||
# before and after the call to Var_ParsePP. | # before and after the call to Var_Parse. | |||
.if empty(W${:UOR}D) | .if empty(W${:UOR}D) | |||
. error | . error | |||
.endif | .endif | |||
# There may be spaces at the outside of the parentheses. | # There may be spaces at the outside of the parentheses. | |||
# Spaces inside the parentheses are interpreted as part of the variable name. | # Spaces inside the parentheses are interpreted as part of the variable name. | |||
.if ! empty ( WORD ) | .if ! empty ( WORD ) | |||
. error | . error | |||
.endif | .endif | |||
${:U WORD }= variable name with spaces | ${:U WORD }= variable name with spaces | |||
# Now there is a variable named " WORD ", and it is not empty. | # Now there is a variable named " WORD ", and it is not empty. | |||
.if empty ( WORD ) | .if empty ( WORD ) | |||
. error | . error | |||
.endif | .endif | |||
# Parse error: missing closing parenthesis. | ||||
.if empty(WORD | ||||
. error | ||||
.else | ||||
. error | ||||
.endif | ||||
all: | all: | |||
@:; | @:; | |||
End of changes. 7 change blocks. | ||||
17 lines changed or deleted | 26 lines changed or added |