| @@ -1,8 +1,122 @@ | | | @@ -1,8 +1,122 @@ |
1 | # $NetBSD: cond-func-empty.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $ | | 1 | # $NetBSD: cond-func-empty.mk,v 1.3 2020/09/03 17:13:42 rillig Exp $ |
2 | # | | 2 | # |
3 | # Tests for the empty() function in .if conditions. | | 3 | # Tests for the empty() function in .if conditions, which tests a variable |
| | | 4 | # expression for emptiness. |
| | | 5 | # |
| | | 6 | # Note that the argument in the parentheses is indeed a variable name, |
| | | 7 | # optionally followed by variable modifiers. This is like the defined() |
| | | 8 | # function. |
| | | 9 | # |
| | | 10 | |
| | | 11 | .undef UNDEF |
| | | 12 | EMPTY= # empty |
| | | 13 | SPACE= ${:U } |
| | | 14 | WORD= word |
| | | 15 | |
| | | 16 | # An undefined variable is 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, and |
| | | 29 | # after that the expression is no longer empty. Because the variable |
| | | 30 | # was undefined in the first place, the expression has the flag VAR_JUNK |
| | | 31 | # but not VAR_KEEP, therefore it is still considered undefined. |
| | | 32 | # |
| | | 33 | # XXX: This is hard to explain to someone who doesn't know these |
| | | 34 | # implementation details. |
| | | 35 | # |
| | | 36 | .if !empty(UNDEF:S,^$,value,W) |
| | | 37 | . error |
| | | 38 | .endif |
| | | 39 | |
| | | 40 | # The :U modifier modifies expressions based on undefined variables |
| | | 41 | # (VAR_JUNK) by adding the VAR_KEEP flag, which marks the expression |
| | | 42 | # as "being interesting enough to be further processed". |
| | | 43 | # |
| | | 44 | .if empty(UNDEF:S,^$,value,W:Ufallback) |
| | | 45 | . error |
| | | 46 | .endif |
| | | 47 | |
| | | 48 | # And now to the surprising part. Applying the following :S modifier to the |
| | | 49 | # undefined variable makes it non-empty, but the marker VAR_JUNK is preserved |
| | | 50 | # nevertheless. The :U modifier that follows only looks at VAR_JUNK to decide |
| | | 51 | # whether the variable is defined or not. This kind of makes sense since the |
| | | 52 | # :U modifier tests the _variable_, not the _expression_. |
| | | 53 | # |
| | | 54 | # But since the variable was undefined to begin with, the fallback value is |
| | | 55 | # used in this expression. |
| | | 56 | # |
| | | 57 | .if ${UNDEF:S,^$,value,W:Ufallback} != "fallback" |
| | | 58 | . error |
| | | 59 | .endif |
| | | 60 | |
| | | 61 | # The variable EMPTY is completely empty (0 characters). |
| | | 62 | .if !empty(EMPTY) |
| | | 63 | . error |
| | | 64 | .endif |
| | | 65 | |
| | | 66 | # The variable SPACE has a single space, which counts as being empty. |
| | | 67 | .if !empty(SPACE) |
| | | 68 | . error |
| | | 69 | .endif |
| | | 70 | |
| | | 71 | # The variable .newline has a single newline, which counts as being empty. |
| | | 72 | .if !empty(.newline) |
| | | 73 | . error |
| | | 74 | .endif |
| | | 75 | |
| | | 76 | # The empty variable named "" gets a fallback value of " ", which counts as |
| | | 77 | # empty. |
| | | 78 | # |
| | | 79 | # Contrary to the other functions in conditionals, the trailing space is not |
| | | 80 | # stripped off, as can be seen in the -dv debug log. If the space had been |
| | | 81 | # stripped, it wouldn't make a difference in this case. |
| | | 82 | # |
| | | 83 | .if !empty(:U ) |
| | | 84 | . error |
| | | 85 | .endif |
| | | 86 | |
| | | 87 | # Now the variable named " " gets a non-empty value, which demonstrates that |
| | | 88 | # neither leading nor trailing spaces are trimmed in the argument of the |
| | | 89 | # function. If the spaces were trimmed, the variable name would be "" and |
| | | 90 | # that variable is indeed undefined. Since get_mpt_arg calls Var_Parse |
| | | 91 | # without VARE_UNDEFERR, the value of the undefined variable is returned as |
| | | 92 | # an empty string. |
| | | 93 | ${:U }= space |
| | | 94 | .if empty( ) |
| | | 95 | . error |
| | | 96 | .endif |
| | | 97 | |
| | | 98 | # The value of the following expression is " word", which is not empty. |
| | | 99 | .if empty(:U word) |
| | | 100 | . error |
| | | 101 | .endif |
| | | 102 | |
| | | 103 | # The :L modifier creates a variable expression that has the same value as |
| | | 104 | # its name, which both are "VAR" in this case. The value is therefore not |
| | | 105 | # empty. |
| | | 106 | .if empty(VAR:L) |
| | | 107 | . error |
| | | 108 | .endif |
| | | 109 | |
| | | 110 | # The variable WORD has the value "word", which does not count as empty. |
| | | 111 | .if empty(WORD) |
| | | 112 | . error |
| | | 113 | .endif |
4 | | | 114 | |
5 | # TODO: Implementation | | 115 | # The expression ${} for a variable with the empty name always evaluates |
| | | 116 | # to an empty string (see Var_Parse, varNoError). |
| | | 117 | .if !empty() |
| | | 118 | . error |
| | | 119 | .endif |
6 | | | 120 | |
7 | all: | | 121 | all: |
8 | @:; | | 122 | @:; |