1*8c973ee2SSimon J. Gerraty# $NetBSD: cond-func-empty.mk,v 1.18 2023/03/04 21:15:30 rillig Exp $ 22c3632d1SSimon J. Gerraty# 3956e45f6SSimon J. Gerraty# Tests for the empty() function in .if conditions, which tests a variable 4956e45f6SSimon J. Gerraty# expression for emptiness. 5956e45f6SSimon J. Gerraty# 612904384SSimon J. Gerraty# Note that the argument in the parentheses is a variable name, not a variable 712904384SSimon J. Gerraty# expression, optionally followed by variable modifiers. 8956e45f6SSimon J. Gerraty# 92c3632d1SSimon J. Gerraty 10956e45f6SSimon J. Gerraty.undef UNDEF 11956e45f6SSimon J. GerratyEMPTY= # empty 12956e45f6SSimon J. GerratySPACE= ${:U } 13956e45f6SSimon J. GerratyWORD= word 14956e45f6SSimon J. Gerraty 15956e45f6SSimon J. Gerraty# An undefined variable is empty. 16956e45f6SSimon J. Gerraty.if !empty(UNDEF) 17956e45f6SSimon J. Gerraty. error 18956e45f6SSimon J. Gerraty.endif 19956e45f6SSimon J. Gerraty 20956e45f6SSimon J. Gerraty# An undefined variable has the empty string as the value, and the :M 21956e45f6SSimon J. Gerraty# variable modifier does not change that. 22956e45f6SSimon J. Gerraty# 23956e45f6SSimon J. Gerraty.if !empty(UNDEF:M*) 24956e45f6SSimon J. Gerraty. error 25956e45f6SSimon J. Gerraty.endif 26956e45f6SSimon J. Gerraty 27*8c973ee2SSimon J. Gerraty# The :S modifier replaces the empty value with an actual word. After 28*8c973ee2SSimon J. Gerraty# applying the :S modifier to the expression, it value is 'empty', so it is 29*8c973ee2SSimon J. Gerraty# no longer empty, but it is still based on an undefined variable. There are 30*8c973ee2SSimon J. Gerraty# a few modifiers that turn an undefined expression into a defined expression, 31*8c973ee2SSimon J. Gerraty# among them :U and :D, but not :S. Therefore, at the end of evaluating the 32*8c973ee2SSimon J. Gerraty# expression, the expression is still undefined, so its final value becomes an 33*8c973ee2SSimon J. Gerraty# empty string. 34956e45f6SSimon J. Gerraty# 35956e45f6SSimon J. Gerraty# XXX: This is hard to explain to someone who doesn't know these 36956e45f6SSimon J. Gerraty# implementation details. 37956e45f6SSimon J. Gerraty# 38956e45f6SSimon J. Gerraty.if !empty(UNDEF:S,^$,value,W) 39956e45f6SSimon J. Gerraty. error 40956e45f6SSimon J. Gerraty.endif 41956e45f6SSimon J. Gerraty 4212904384SSimon J. Gerraty# The :U modifier changes the state of a previously undefined expression from 4312904384SSimon J. Gerraty# DEF_UNDEF to DEF_DEFINED. This marks the expression as "being interesting 4412904384SSimon J. Gerraty# enough to be further processed". 45956e45f6SSimon J. Gerraty# 46956e45f6SSimon J. Gerraty.if empty(UNDEF:S,^$,value,W:Ufallback) 47956e45f6SSimon J. Gerraty. error 48956e45f6SSimon J. Gerraty.endif 49956e45f6SSimon J. Gerraty 50*8c973ee2SSimon J. Gerraty# When an expression is based on an undefined variable, its modifiers interact 51*8c973ee2SSimon J. Gerraty# in sometimes surprising ways. Applying the :S modifier to the undefined 52*8c973ee2SSimon J. Gerraty# expression makes its value non-empty, but doesn't change that the expression 53*8c973ee2SSimon J. Gerraty# is based on an undefined variable. The :U modifier that follows only looks 54*8c973ee2SSimon J. Gerraty# at the definedness state to decide whether the variable is defined or not. 55*8c973ee2SSimon J. Gerraty# This kind of makes sense since the :U modifier tests the _variable_, not the 56e2eeea75SSimon J. Gerraty# _expression_. 57956e45f6SSimon J. Gerraty# 58*8c973ee2SSimon J. Gerraty# Since the variable was undefined to begin with, the fallback value from the 59*8c973ee2SSimon J. Gerraty# :U modifier is used in this expression, instead of keeping the 'value' from 60*8c973ee2SSimon J. Gerraty# the :S modifier. 61956e45f6SSimon J. Gerraty# 62956e45f6SSimon J. Gerraty.if ${UNDEF:S,^$,value,W:Ufallback} != "fallback" 63956e45f6SSimon J. Gerraty. error 64956e45f6SSimon J. Gerraty.endif 65956e45f6SSimon J. Gerraty 66956e45f6SSimon J. Gerraty# The variable EMPTY is completely empty (0 characters). 67956e45f6SSimon J. Gerraty.if !empty(EMPTY) 68956e45f6SSimon J. Gerraty. error 69956e45f6SSimon J. Gerraty.endif 70956e45f6SSimon J. Gerraty 71956e45f6SSimon J. Gerraty# The variable SPACE has a single space, which counts as being empty. 72956e45f6SSimon J. Gerraty.if !empty(SPACE) 73956e45f6SSimon J. Gerraty. error 74956e45f6SSimon J. Gerraty.endif 75956e45f6SSimon J. Gerraty 76956e45f6SSimon J. Gerraty# The variable .newline has a single newline, which counts as being empty. 77956e45f6SSimon J. Gerraty.if !empty(.newline) 78956e45f6SSimon J. Gerraty. error 79956e45f6SSimon J. Gerraty.endif 80956e45f6SSimon J. Gerraty 8112904384SSimon J. Gerraty# The following example constructs an expression with the variable name "" 8212904384SSimon J. Gerraty# and the value " ". This expression counts as empty since the value contains 8312904384SSimon J. Gerraty# only whitespace. 84956e45f6SSimon J. Gerraty# 85956e45f6SSimon J. Gerraty# Contrary to the other functions in conditionals, the trailing space is not 86956e45f6SSimon J. Gerraty# stripped off, as can be seen in the -dv debug log. If the space had been 8712904384SSimon J. Gerraty# stripped, it wouldn't make a difference in this case, but in other cases. 88956e45f6SSimon J. Gerraty# 89956e45f6SSimon J. Gerraty.if !empty(:U ) 90956e45f6SSimon J. Gerraty. error 91956e45f6SSimon J. Gerraty.endif 92956e45f6SSimon J. Gerraty 93956e45f6SSimon J. Gerraty# Now the variable named " " gets a non-empty value, which demonstrates that 94956e45f6SSimon J. Gerraty# neither leading nor trailing spaces are trimmed in the argument of the 95956e45f6SSimon J. Gerraty# function. If the spaces were trimmed, the variable name would be "" and 9612904384SSimon J. Gerraty# that variable is indeed undefined. Since CondParser_FuncCallEmpty calls 97*8c973ee2SSimon J. Gerraty# Var_Parse without VARE_UNDEFERR, the value of the undefined variable "" 98*8c973ee2SSimon J. Gerraty# would be returned as an empty string. 99956e45f6SSimon J. Gerraty${:U }= space 100956e45f6SSimon J. Gerraty.if empty( ) 101956e45f6SSimon J. Gerraty. error 102956e45f6SSimon J. Gerraty.endif 103956e45f6SSimon J. Gerraty 104956e45f6SSimon J. Gerraty# The value of the following expression is " word", which is not empty. 105956e45f6SSimon J. Gerraty.if empty(:U word) 106956e45f6SSimon J. Gerraty. error 107956e45f6SSimon J. Gerraty.endif 108956e45f6SSimon J. Gerraty 109956e45f6SSimon J. Gerraty# The :L modifier creates a variable expression that has the same value as 110956e45f6SSimon J. Gerraty# its name, which both are "VAR" in this case. The value is therefore not 111956e45f6SSimon J. Gerraty# empty. 112956e45f6SSimon J. Gerraty.if empty(VAR:L) 113956e45f6SSimon J. Gerraty. error 114956e45f6SSimon J. Gerraty.endif 115956e45f6SSimon J. Gerraty 116956e45f6SSimon J. Gerraty# The variable WORD has the value "word", which does not count as empty. 117956e45f6SSimon J. Gerraty.if empty(WORD) 118956e45f6SSimon J. Gerraty. error 119956e45f6SSimon J. Gerraty.endif 120956e45f6SSimon J. Gerraty 121956e45f6SSimon J. Gerraty# The expression ${} for a variable with the empty name always evaluates 122956e45f6SSimon J. Gerraty# to an empty string (see Var_Parse, varUndefined). 123956e45f6SSimon J. Gerraty.if !empty() 124956e45f6SSimon J. Gerraty. error 125956e45f6SSimon J. Gerraty.endif 126956e45f6SSimon J. Gerraty 127*8c973ee2SSimon J. Gerraty# Ensure that variable expressions that appear as part of the function call 128*8c973ee2SSimon J. Gerraty# argument are properly parsed. Typical use cases for this are .for loops, 129*8c973ee2SSimon J. Gerraty# which are expanded to exactly these ${:U} expressions. 130956e45f6SSimon J. Gerraty# 131956e45f6SSimon J. Gerraty# If everything goes well, the argument expands to "WORD", and that variable 132956e45f6SSimon J. Gerraty# is defined at the beginning of this file. The surrounding 'W' and 'D' 13312904384SSimon J. Gerraty# ensure that CondParser_FuncCallEmpty keeps track of the parsing position, 13412904384SSimon J. Gerraty# both before and after the call to Var_Parse. 135956e45f6SSimon J. Gerraty.if empty(W${:UOR}D) 136956e45f6SSimon J. Gerraty. error 137956e45f6SSimon J. Gerraty.endif 138956e45f6SSimon J. Gerraty 139956e45f6SSimon J. Gerraty# There may be spaces at the outside of the parentheses. 140956e45f6SSimon J. Gerraty# Spaces inside the parentheses are interpreted as part of the variable name. 141956e45f6SSimon J. Gerraty.if ! empty ( WORD ) 142956e45f6SSimon J. Gerraty. error 143956e45f6SSimon J. Gerraty.endif 144956e45f6SSimon J. Gerraty 145956e45f6SSimon J. Gerraty${:U WORD }= variable name with spaces 146956e45f6SSimon J. Gerraty 147956e45f6SSimon J. Gerraty# Now there is a variable named " WORD ", and it is not empty. 148956e45f6SSimon J. Gerraty.if empty ( WORD ) 149956e45f6SSimon J. Gerraty. error 150956e45f6SSimon J. Gerraty.endif 1512c3632d1SSimon J. Gerraty 152e2eeea75SSimon J. Gerraty# Parse error: missing closing parenthesis. 153e2eeea75SSimon J. Gerraty.if empty(WORD 154e2eeea75SSimon J. Gerraty. error 155e2eeea75SSimon J. Gerraty.else 156e2eeea75SSimon J. Gerraty. error 157e2eeea75SSimon J. Gerraty.endif 158e2eeea75SSimon J. Gerraty 15912904384SSimon J. Gerraty# Since cond.c 1.76 from 2020-06-28 and before var.c 1.226 from 2020-07-02, 16012904384SSimon J. Gerraty# the following example generated a wrong error message "Variable VARNAME is 16112904384SSimon J. Gerraty# recursive". 16206b9b3e0SSimon J. Gerraty# 16312904384SSimon J. Gerraty# Since at least 1993, the manual page claimed that irrelevant parts of 16412904384SSimon J. Gerraty# conditions were not evaluated, but that was wrong for a long time. The 16512904384SSimon J. Gerraty# expressions in irrelevant parts of the condition were actually evaluated, 166*8c973ee2SSimon J. Gerraty# they just allowed undefined variables to be used in the conditions. These 167*8c973ee2SSimon J. Gerraty# unnecessary evaluations were fixed in several commits, starting with var.c 168*8c973ee2SSimon J. Gerraty# 1.226 from 2020-07-02. 16912904384SSimon J. Gerraty# 17012904384SSimon J. Gerraty# In this example, the variable "VARNAME2" is not defined, so evaluation of 17112904384SSimon J. Gerraty# the condition should have stopped at this point, and the rest of the 17212904384SSimon J. Gerraty# condition should have been processed in parse-only mode. The right-hand 17312904384SSimon J. Gerraty# side containing the '!empty' was evaluated though, as it had always been. 17406b9b3e0SSimon J. Gerraty# 17506b9b3e0SSimon J. Gerraty# When evaluating the !empty condition, the variable name was parsed as 17606b9b3e0SSimon J. Gerraty# "VARNAME${:U2}", but without expanding any nested variable expression, in 17712904384SSimon J. Gerraty# this case the ${:U2}. The expression '${:U2}' was replaced with an empty 17812904384SSimon J. Gerraty# string, the resulting variable name was thus "VARNAME". This conceptually 17912904384SSimon J. Gerraty# wrong variable name should have been discarded quickly after parsing it, to 18012904384SSimon J. Gerraty# prevent it from doing any harm. 18106b9b3e0SSimon J. Gerraty# 18206b9b3e0SSimon J. Gerraty# The variable expression was expanded though, and this was wrong. The 183b0c40a00SSimon J. Gerraty# expansion was done without VARE_WANTRES (called VARF_WANTRES back 18406b9b3e0SSimon J. Gerraty# then) though. This had the effect that the ${:U1} from the value of VARNAME 18506b9b3e0SSimon J. Gerraty# expanded to an empty string. This in turn created the seemingly recursive 18606b9b3e0SSimon J. Gerraty# definition VARNAME=${VARNAME}, and that definition was never meant to be 18706b9b3e0SSimon J. Gerraty# expanded. 18806b9b3e0SSimon J. Gerraty# 18906b9b3e0SSimon J. Gerraty# This was fixed by expanding nested variable expressions in the variable name 19006b9b3e0SSimon J. Gerraty# only if the flag VARE_WANTRES is given. 19106b9b3e0SSimon J. GerratyVARNAME= ${VARNAME${:U1}} 19206b9b3e0SSimon J. Gerraty.if defined(VARNAME${:U2}) && !empty(VARNAME${:U2}) 19306b9b3e0SSimon J. Gerraty.endif 19406b9b3e0SSimon J. Gerraty 1959f45a3c8SSimon J. Gerraty 1969f45a3c8SSimon J. Gerraty# If the word 'empty' is not followed by '(', it is not a function call but an 1979f45a3c8SSimon J. Gerraty# ordinary bare word. This bare word is interpreted as 'defined(empty)', and 1989f45a3c8SSimon J. Gerraty# since there is no variable named 'empty', the condition evaluates to false. 1999f45a3c8SSimon J. Gerraty.if empty 2009f45a3c8SSimon J. Gerraty. error 2019f45a3c8SSimon J. Gerraty.endif 2029f45a3c8SSimon J. Gerraty 2039f45a3c8SSimon J. Gerratyempty= # defined but empty 2049f45a3c8SSimon J. Gerraty.if empty 2059f45a3c8SSimon J. Gerraty.else 2069f45a3c8SSimon J. Gerraty. error 2079f45a3c8SSimon J. Gerraty.endif 208