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