1# $NetBSD: cond-func-empty.mk,v 1.24 2023/12/19 19:33:40 rillig Exp $ 2# 3# Tests for the empty() function in .if conditions, which tests an 4# expression for emptiness. 5# 6# Note that the argument in the parentheses is a variable name, not an 7# expression. That name may be followed by ':...' modifiers. 8# 9 10.undef UNDEF 11EMPTY= # empty 12SPACE= ${:U } 13ZERO= 0 14WORD= word 15 16# An undefined variable counts as empty. 17.if !empty(UNDEF) 18. error 19.endif 20 21# An undefined variable has the empty string as the value, and the :M 22# variable modifier does not change that. 23# 24.if !empty(UNDEF:M*) 25. error 26.endif 27 28# The :S modifier replaces the empty value with an actual word. After 29# applying the :S modifier to the expression, its value is 'empty', so it is 30# no longer empty, but it is still based on an undefined variable. There are 31# a few modifiers that turn an undefined expression into a defined expression, 32# among them :U and :D, but not :S. Therefore, at the end of evaluating the 33# expression, the expression is still undefined, so its final value becomes an 34# empty string. 35# 36# XXX: This is hard to explain to someone who doesn't know these 37# implementation details. 38# 39.if !empty(UNDEF:S,^$,value,W) 40. error 41.endif 42 43# The :U modifier changes the state of a previously undefined expression from 44# DEF_UNDEF to DEF_DEFINED. This marks the expression as "being interesting 45# enough to be further processed". 46# 47.if empty(UNDEF:S,^$,value,W:Ufallback) 48. error 49.endif 50 51# When an expression is based on an undefined variable, its modifiers interact 52# in sometimes surprising ways. Applying the :S modifier to the undefined 53# expression makes its value non-empty, but doesn't change that the expression 54# is based on an undefined variable. The :U modifier that follows only looks 55# at the definedness state to decide whether the variable is defined or not. 56# This kind of makes sense since the :U modifier tests the _variable_, not the 57# _expression_. 58# 59# Since the variable was undefined to begin with, the fallback value from the 60# :U modifier is used in this expression, instead of keeping the 'value' from 61# the :S modifier. 62# 63.if ${UNDEF:S,^$,value,W:Ufallback} != "fallback" 64. error 65.endif 66 67# The variable EMPTY is completely empty (0 characters). 68.if !empty(EMPTY) 69. error 70.endif 71 72# The variable SPACE has a single space, which counts as being empty. 73.if !empty(SPACE) 74. error 75.endif 76 77# The variable .newline has a single newline, which counts as being empty. 78.if !empty(.newline) 79. error 80.endif 81 82# The variable ZERO has the numeric value 0, but is not empty. This is a 83# subtle difference between using either 'empty(ZERO)' or the expression 84# '${ZERO}' in a condition. 85.if empty(ZERO) 86. error 87.elif ${ZERO} 88. error 89.elif ${ZERO} == "" 90. error 91.endif 92 93# The following example constructs an expression with the variable name "" 94# and the value " ". This expression counts as empty since the value contains 95# only whitespace. 96# 97# Contrary to the other functions in conditionals, the trailing space is not 98# stripped off, as can be seen in the -dv debug log. If the space had been 99# stripped, it wouldn't make a difference in this case, but in other cases. 100# 101.if !empty(:U ) 102. error 103.endif 104 105# Now the variable named " " gets a non-empty value, which demonstrates that 106# neither leading nor trailing spaces are trimmed in the argument of the 107# function. If the spaces were trimmed, the variable name would be "" and 108# that variable is indeed undefined. Since CondParser_FuncCallEmpty calls 109# Var_Parse without VARE_UNDEFERR, the value of the undefined variable "" 110# would be returned as an empty string. 111${:U }= space 112.if empty( ) 113. error 114.endif 115 116# The value of the following expression is " word", which is not empty. To be 117# empty, _all_ characters in the expression value have to be whitespace, not 118# only the first. 119.if empty(:U word) 120. error 121.endif 122 123# The :L modifier creates an expression that has the same value as 124# its name, which both are "VAR" in this case. The value is therefore not 125# empty. 126.if empty(VAR:L) 127. error 128.endif 129 130# The variable WORD has the value "word", which does not count as empty. 131.if empty(WORD) 132. error 133.endif 134 135# The expression ${} for a variable with the empty name always evaluates 136# to an empty string (see Var_Parse, varUndefined). 137.if !empty() 138. error 139.endif 140 141# Ensure that expressions that appear as part of the function call 142# argument are properly parsed. Typical use cases for this are .for loops, 143# which are expanded to exactly these ${:U} expressions. 144# 145# The argument expands to "WORD", and that variable is defined at the 146# beginning of this file. The surrounding 'W' and 'D' ensure that 147# CondParser_FuncCallEmpty keeps track of the parsing position, both before 148# and after the call to Var_Parse. 149.if empty(W${:UOR}D) 150. error 151.endif 152 153# There may be spaces outside the parentheses. 154# Spaces inside the parentheses are interpreted as part of the variable name. 155.if ! empty ( WORD ) 156. error 157.endif 158 159${:U WORD }= variable name with spaces 160 161# Now there is a variable named " WORD ", and it is not empty. 162.if empty ( WORD ) 163. error 164.endif 165 166# expect+2: Unclosed variable "WORD" 167# expect+1: Malformed conditional (empty(WORD) 168.if empty(WORD 169. error 170.else 171. error 172.endif 173 174# Since cond.c 1.76 from 2020-06-28 and before var.c 1.226 from 2020-07-02, 175# the following example generated a wrong error message "Variable VARNAME is 176# recursive". 177# 178# Since at least 1993, the manual page claimed that irrelevant parts of 179# conditions were not evaluated, but that was wrong for a long time. The 180# expressions in irrelevant parts of the condition were actually evaluated, 181# they just allowed undefined variables to be used in the conditions. These 182# unnecessary evaluations were fixed in several commits, starting with var.c 183# 1.226 from 2020-07-02. 184# 185# In this example, the variable "VARNAME2" is not defined, so evaluation of 186# the condition should have stopped at this point, and the rest of the 187# condition should have been processed in parse-only mode. The right-hand 188# side containing the '!empty' was evaluated though, as it had always been. 189# 190# When evaluating the !empty condition, the variable name was parsed as 191# "VARNAME${:U2}", but without expanding any nested expression, in 192# this case the ${:U2}. The expression '${:U2}' was replaced with an empty 193# string, the resulting variable name was thus "VARNAME". This conceptually 194# wrong variable name should have been discarded quickly after parsing it, to 195# prevent it from doing any harm. 196# 197# The expression was expanded, and this was wrong. The 198# expansion was done without VARE_WANTRES (called VARF_WANTRES back then) 199# though. This had the effect that the ${:U1} from the value of VARNAME 200# expanded to an empty string. This in turn created the seemingly recursive 201# definition VARNAME=${VARNAME}, and that definition was never meant to be 202# expanded. 203# 204# This was fixed by expanding nested expressions in the variable name 205# only if the flag VARE_WANTRES is given. 206VARNAME= ${VARNAME${:U1}} 207.if defined(VARNAME${:U2}) && !empty(VARNAME${:U2}) 208.endif 209 210 211# If the word 'empty' is not followed by '(', it is not a function call but an 212# ordinary bare word. This bare word is interpreted as 'defined(empty)', and 213# since there is no variable named 'empty', the condition evaluates to false. 214.if empty 215. error 216.endif 217 218empty= # defined but empty 219.if empty 220.else 221. error 222.endif 223