1*6a7405f5SSimon J. Gerraty# $NetBSD: cond-func-empty.mk,v 1.28 2025/01/11 20:54:45 rillig Exp $ 22c3632d1SSimon J. Gerraty# 3d5e0a182SSimon J. Gerraty# Tests for the empty() function in .if conditions, which tests an 4956e45f6SSimon J. Gerraty# expression for emptiness. 5956e45f6SSimon J. Gerraty# 6d5e0a182SSimon J. Gerraty# Note that the argument in the parentheses is a variable name, not an 798875883SSimon J. Gerraty# expression. That name may be followed by ':...' modifiers. 8956e45f6SSimon J. Gerraty# 92c3632d1SSimon J. Gerraty 10956e45f6SSimon J. Gerraty.undef UNDEF 11956e45f6SSimon J. GerratyEMPTY= # empty 12956e45f6SSimon J. GerratySPACE= ${:U } 1398875883SSimon J. GerratyZERO= 0 14956e45f6SSimon J. GerratyWORD= word 15956e45f6SSimon J. Gerraty 1698875883SSimon J. Gerraty# An undefined variable counts as empty. 17956e45f6SSimon J. Gerraty.if !empty(UNDEF) 18956e45f6SSimon J. Gerraty. error 19956e45f6SSimon J. Gerraty.endif 20956e45f6SSimon J. Gerraty 21956e45f6SSimon J. Gerraty# An undefined variable has the empty string as the value, and the :M 22956e45f6SSimon J. Gerraty# variable modifier does not change that. 23956e45f6SSimon J. Gerraty# 24956e45f6SSimon J. Gerraty.if !empty(UNDEF:M*) 25956e45f6SSimon J. Gerraty. error 26956e45f6SSimon J. Gerraty.endif 27956e45f6SSimon J. Gerraty 288c973ee2SSimon J. Gerraty# The :S modifier replaces the empty value with an actual word. After 29148ee845SSimon J. Gerraty# applying the :S modifier to the expression, its value is 'empty', so it is 308c973ee2SSimon J. Gerraty# no longer empty, but it is still based on an undefined variable. There are 318c973ee2SSimon J. Gerraty# a few modifiers that turn an undefined expression into a defined expression, 328c973ee2SSimon J. Gerraty# among them :U and :D, but not :S. Therefore, at the end of evaluating the 338c973ee2SSimon J. Gerraty# expression, the expression is still undefined, so its final value becomes an 348c973ee2SSimon J. Gerraty# empty string. 35956e45f6SSimon J. Gerraty# 36956e45f6SSimon J. Gerraty# XXX: This is hard to explain to someone who doesn't know these 37956e45f6SSimon J. Gerraty# implementation details. 38956e45f6SSimon J. Gerraty# 39956e45f6SSimon J. Gerraty.if !empty(UNDEF:S,^$,value,W) 40956e45f6SSimon J. Gerraty. error 41956e45f6SSimon J. Gerraty.endif 42956e45f6SSimon J. Gerraty 4312904384SSimon J. Gerraty# The :U modifier changes the state of a previously undefined expression from 4412904384SSimon J. Gerraty# DEF_UNDEF to DEF_DEFINED. This marks the expression as "being interesting 4512904384SSimon J. Gerraty# enough to be further processed". 46956e45f6SSimon J. Gerraty# 47956e45f6SSimon J. Gerraty.if empty(UNDEF:S,^$,value,W:Ufallback) 48956e45f6SSimon J. Gerraty. error 49956e45f6SSimon J. Gerraty.endif 50956e45f6SSimon J. Gerraty 518c973ee2SSimon J. Gerraty# When an expression is based on an undefined variable, its modifiers interact 528c973ee2SSimon J. Gerraty# in sometimes surprising ways. Applying the :S modifier to the undefined 538c973ee2SSimon J. Gerraty# expression makes its value non-empty, but doesn't change that the expression 548c973ee2SSimon J. Gerraty# is based on an undefined variable. The :U modifier that follows only looks 558c973ee2SSimon J. Gerraty# at the definedness state to decide whether the variable is defined or not. 568c973ee2SSimon J. Gerraty# This kind of makes sense since the :U modifier tests the _variable_, not the 57e2eeea75SSimon J. Gerraty# _expression_. 58956e45f6SSimon J. Gerraty# 598c973ee2SSimon J. Gerraty# Since the variable was undefined to begin with, the fallback value from the 608c973ee2SSimon J. Gerraty# :U modifier is used in this expression, instead of keeping the 'value' from 618c973ee2SSimon J. Gerraty# the :S modifier. 62956e45f6SSimon J. Gerraty# 63956e45f6SSimon J. Gerraty.if ${UNDEF:S,^$,value,W:Ufallback} != "fallback" 64956e45f6SSimon J. Gerraty. error 65956e45f6SSimon J. Gerraty.endif 66956e45f6SSimon J. Gerraty 67956e45f6SSimon J. Gerraty# The variable EMPTY is completely empty (0 characters). 68956e45f6SSimon J. Gerraty.if !empty(EMPTY) 69956e45f6SSimon J. Gerraty. error 70956e45f6SSimon J. Gerraty.endif 71956e45f6SSimon J. Gerraty 72956e45f6SSimon J. Gerraty# The variable SPACE has a single space, which counts as being empty. 73956e45f6SSimon J. Gerraty.if !empty(SPACE) 74956e45f6SSimon J. Gerraty. error 75956e45f6SSimon J. Gerraty.endif 76956e45f6SSimon J. Gerraty 77956e45f6SSimon J. Gerraty# The variable .newline has a single newline, which counts as being empty. 78956e45f6SSimon J. Gerraty.if !empty(.newline) 79956e45f6SSimon J. Gerraty. error 80956e45f6SSimon J. Gerraty.endif 81956e45f6SSimon J. Gerraty 8298875883SSimon J. Gerraty# The variable ZERO has the numeric value 0, but is not empty. This is a 8398875883SSimon J. Gerraty# subtle difference between using either 'empty(ZERO)' or the expression 8498875883SSimon J. Gerraty# '${ZERO}' in a condition. 8598875883SSimon J. Gerraty.if empty(ZERO) 8698875883SSimon J. Gerraty. error 8798875883SSimon J. Gerraty.elif ${ZERO} 8898875883SSimon J. Gerraty. error 8998875883SSimon J. Gerraty.elif ${ZERO} == "" 9098875883SSimon J. Gerraty. error 9198875883SSimon J. Gerraty.endif 9298875883SSimon J. Gerraty 9312904384SSimon J. Gerraty# The following example constructs an expression with the variable name "" 9412904384SSimon J. Gerraty# and the value " ". This expression counts as empty since the value contains 9512904384SSimon J. Gerraty# only whitespace. 96956e45f6SSimon J. Gerraty# 97956e45f6SSimon J. Gerraty# Contrary to the other functions in conditionals, the trailing space is not 98956e45f6SSimon J. Gerraty# stripped off, as can be seen in the -dv debug log. If the space had been 9912904384SSimon J. Gerraty# stripped, it wouldn't make a difference in this case, but in other cases. 100956e45f6SSimon J. Gerraty# 101956e45f6SSimon J. Gerraty.if !empty(:U ) 102956e45f6SSimon J. Gerraty. error 103956e45f6SSimon J. Gerraty.endif 104956e45f6SSimon J. Gerraty 105956e45f6SSimon J. Gerraty# Now the variable named " " gets a non-empty value, which demonstrates that 106956e45f6SSimon J. Gerraty# neither leading nor trailing spaces are trimmed in the argument of the 1078d5c8e21SSimon J. Gerraty# function. If the spaces were trimmed, the variable name would be "", and 1088d5c8e21SSimon J. Gerraty# that variable is indeed undefined. Since CondParser_FuncCallEmpty allows 1098d5c8e21SSimon J. Gerraty# subexpressions to be based on undefined variables, the value of the 1108d5c8e21SSimon J. Gerraty# undefined variable "" would be returned as an empty string. 111956e45f6SSimon J. Gerraty${:U }= space 112956e45f6SSimon J. Gerraty.if empty( ) 113956e45f6SSimon J. Gerraty. error 114956e45f6SSimon J. Gerraty.endif 115956e45f6SSimon J. Gerraty 11698875883SSimon J. Gerraty# The value of the following expression is " word", which is not empty. To be 11798875883SSimon J. Gerraty# empty, _all_ characters in the expression value have to be whitespace, not 11898875883SSimon J. Gerraty# only the first. 119956e45f6SSimon J. Gerraty.if empty(:U word) 120956e45f6SSimon J. Gerraty. error 121956e45f6SSimon J. Gerraty.endif 122956e45f6SSimon J. Gerraty 123d5e0a182SSimon J. Gerraty# The :L modifier creates an expression that has the same value as 124956e45f6SSimon J. Gerraty# its name, which both are "VAR" in this case. The value is therefore not 125956e45f6SSimon J. Gerraty# empty. 126956e45f6SSimon J. Gerraty.if empty(VAR:L) 127956e45f6SSimon J. Gerraty. error 128956e45f6SSimon J. Gerraty.endif 129956e45f6SSimon J. Gerraty 130956e45f6SSimon J. Gerraty# The variable WORD has the value "word", which does not count as empty. 131956e45f6SSimon J. Gerraty.if empty(WORD) 132956e45f6SSimon J. Gerraty. error 133956e45f6SSimon J. Gerraty.endif 134956e45f6SSimon J. Gerraty 135956e45f6SSimon J. Gerraty# The expression ${} for a variable with the empty name always evaluates 136956e45f6SSimon J. Gerraty# to an empty string (see Var_Parse, varUndefined). 137956e45f6SSimon J. Gerraty.if !empty() 138956e45f6SSimon J. Gerraty. error 139956e45f6SSimon J. Gerraty.endif 140956e45f6SSimon J. Gerraty 141d5e0a182SSimon J. Gerraty# Ensure that expressions that appear as part of the function call 1428c973ee2SSimon J. Gerraty# argument are properly parsed. Typical use cases for this are .for loops, 1438c973ee2SSimon J. Gerraty# which are expanded to exactly these ${:U} expressions. 144956e45f6SSimon J. Gerraty# 14598875883SSimon J. Gerraty# The argument expands to "WORD", and that variable is defined at the 14698875883SSimon J. Gerraty# beginning of this file. The surrounding 'W' and 'D' ensure that 14798875883SSimon J. Gerraty# CondParser_FuncCallEmpty keeps track of the parsing position, both before 14898875883SSimon J. Gerraty# and after the call to Var_Parse. 149956e45f6SSimon J. Gerraty.if empty(W${:UOR}D) 150956e45f6SSimon J. Gerraty. error 151956e45f6SSimon J. Gerraty.endif 152956e45f6SSimon J. Gerraty 15398875883SSimon J. Gerraty# There may be spaces outside the parentheses. 154956e45f6SSimon J. Gerraty# Spaces inside the parentheses are interpreted as part of the variable name. 155956e45f6SSimon J. Gerraty.if ! empty ( WORD ) 156956e45f6SSimon J. Gerraty. error 157956e45f6SSimon J. Gerraty.endif 158956e45f6SSimon J. Gerraty 159956e45f6SSimon J. Gerraty${:U WORD }= variable name with spaces 160956e45f6SSimon J. Gerraty 161956e45f6SSimon J. Gerraty# Now there is a variable named " WORD ", and it is not empty. 162956e45f6SSimon J. Gerraty.if empty ( WORD ) 163956e45f6SSimon J. Gerraty. error 164956e45f6SSimon J. Gerraty.endif 1652c3632d1SSimon J. Gerraty 166*6a7405f5SSimon J. Gerraty# expect+1: Unclosed variable "WORD" 167e2eeea75SSimon J. Gerraty.if empty(WORD 168e2eeea75SSimon J. Gerraty. error 169e2eeea75SSimon J. Gerraty.else 170e2eeea75SSimon J. Gerraty. error 171e2eeea75SSimon J. Gerraty.endif 172e2eeea75SSimon J. Gerraty 17312904384SSimon J. Gerraty# Since cond.c 1.76 from 2020-06-28 and before var.c 1.226 from 2020-07-02, 17412904384SSimon J. Gerraty# the following example generated a wrong error message "Variable VARNAME is 17512904384SSimon J. Gerraty# recursive". 17606b9b3e0SSimon J. Gerraty# 17712904384SSimon J. Gerraty# Since at least 1993, the manual page claimed that irrelevant parts of 17812904384SSimon J. Gerraty# conditions were not evaluated, but that was wrong for a long time. The 17912904384SSimon J. Gerraty# expressions in irrelevant parts of the condition were actually evaluated, 1808c973ee2SSimon J. Gerraty# they just allowed undefined variables to be used in the conditions. These 1818c973ee2SSimon J. Gerraty# unnecessary evaluations were fixed in several commits, starting with var.c 1828c973ee2SSimon J. Gerraty# 1.226 from 2020-07-02. 18312904384SSimon J. Gerraty# 18412904384SSimon J. Gerraty# In this example, the variable "VARNAME2" is not defined, so evaluation of 18512904384SSimon J. Gerraty# the condition should have stopped at this point, and the rest of the 18612904384SSimon J. Gerraty# condition should have been processed in parse-only mode. The right-hand 18712904384SSimon J. Gerraty# side containing the '!empty' was evaluated though, as it had always been. 18806b9b3e0SSimon J. Gerraty# 18906b9b3e0SSimon J. Gerraty# When evaluating the !empty condition, the variable name was parsed as 190d5e0a182SSimon J. Gerraty# "VARNAME${:U2}", but without expanding any nested expression, in 19112904384SSimon J. Gerraty# this case the ${:U2}. The expression '${:U2}' was replaced with an empty 19212904384SSimon J. Gerraty# string, the resulting variable name was thus "VARNAME". This conceptually 19312904384SSimon J. Gerraty# wrong variable name should have been discarded quickly after parsing it, to 19412904384SSimon J. Gerraty# prevent it from doing any harm. 19506b9b3e0SSimon J. Gerraty# 1968d5c8e21SSimon J. Gerraty# The expression was evaluated, and this was wrong. The evaluation was done 1978d5c8e21SSimon J. Gerraty# without VARE_EVAL (called VARF_WANTRES back then) though. This had the 1988d5c8e21SSimon J. Gerraty# effect that the ${:U1} from the value of VARNAME evaluated to an empty 1998d5c8e21SSimon J. Gerraty# string. This in turn created the seemingly recursive definition 2008d5c8e21SSimon J. Gerraty# VARNAME=${VARNAME}, and that definition was evaluated even though it was 2018d5c8e21SSimon J. Gerraty# never meant to be evaluated. 20206b9b3e0SSimon J. Gerraty# 2038d5c8e21SSimon J. Gerraty# This was fixed by evaluating nested expressions in the variable name only 2048d5c8e21SSimon J. Gerraty# when the whole expression was evaluated as well. 20506b9b3e0SSimon J. GerratyVARNAME= ${VARNAME${:U1}} 20606b9b3e0SSimon J. Gerraty.if defined(VARNAME${:U2}) && !empty(VARNAME${:U2}) 20706b9b3e0SSimon J. Gerraty.endif 20806b9b3e0SSimon J. Gerraty 209*6a7405f5SSimon J. Gerraty# Expressions in the argument of a function call don't have to be defined. 210*6a7405f5SSimon J. Gerraty.if !empty(${UNDEF}) 211*6a7405f5SSimon J. Gerraty. error 212*6a7405f5SSimon J. Gerraty.endif 2139f45a3c8SSimon J. Gerraty 2149f45a3c8SSimon J. Gerraty# If the word 'empty' is not followed by '(', it is not a function call but an 2159f45a3c8SSimon J. Gerraty# ordinary bare word. This bare word is interpreted as 'defined(empty)', and 2169f45a3c8SSimon J. Gerraty# since there is no variable named 'empty', the condition evaluates to false. 2179f45a3c8SSimon J. Gerraty.if empty 2189f45a3c8SSimon J. Gerraty. error 2199f45a3c8SSimon J. Gerraty.endif 2209f45a3c8SSimon J. Gerraty 2219f45a3c8SSimon J. Gerratyempty= # defined but empty 2229f45a3c8SSimon J. Gerraty.if empty 2239f45a3c8SSimon J. Gerraty.else 2249f45a3c8SSimon J. Gerraty. error 2259f45a3c8SSimon J. Gerraty.endif 226