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