Home | History | Annotate | Line # | Download | only in unit-tests
      1  1.16  rillig # $NetBSD: varmod-defined.mk,v 1.16 2023/11/19 21:47:52 rillig Exp $
      2   1.1  rillig #
      3   1.2  rillig # Tests for the :D variable modifier, which returns the given string
      4   1.2  rillig # if the variable is defined.  It is closely related to the :U modifier.
      5   1.1  rillig 
      6  1.12  rillig # Force the test results to be independent of the default value of this
      7  1.12  rillig # setting, which is 'yes' for NetBSD's usr.bin/make but 'no' for the bmake
      8  1.12  rillig # distribution and pkgsrc/devel/bmake.
      9   1.9  rillig .MAKE.SAVE_DOLLARS=	yes
     10   1.9  rillig 
     11   1.3  rillig DEF=	defined
     12   1.3  rillig .undef UNDEF
     13   1.3  rillig 
     14   1.3  rillig # Since DEF is defined, the value of the expression is "value", not
     15   1.3  rillig # "defined".
     16   1.3  rillig #
     17   1.3  rillig .if ${DEF:Dvalue} != "value"
     18   1.7  rillig .  error
     19   1.3  rillig .endif
     20   1.3  rillig 
     21   1.3  rillig # Since UNDEF is not defined, the "value" is ignored.  Instead of leaving the
     22   1.3  rillig # expression undefined, it is set to "", exactly to allow the expression to
     23   1.3  rillig # be used in .if conditions.  In this place, other undefined expressions
     24   1.3  rillig # would generate an error message.
     25   1.3  rillig # XXX: Ideally the error message would be "undefined variable", but as of
     26   1.3  rillig # 2020-08-25 it is "Malformed conditional".
     27   1.3  rillig #
     28   1.3  rillig .if ${UNDEF:Dvalue} != ""
     29   1.7  rillig .  error
     30   1.3  rillig .endif
     31   1.1  rillig 
     32   1.4  rillig # The modifier text may contain plain text as well as expressions.
     33   1.4  rillig #
     34   1.4  rillig .if ${DEF:D<${DEF}>} != "<defined>"
     35   1.4  rillig .  error
     36   1.4  rillig .endif
     37   1.4  rillig 
     38   1.4  rillig # Special characters that would be interpreted differently can be escaped.
     39   1.4  rillig # These are '}' (the closing character of the expression), ':', '$' and '\'.
     40   1.4  rillig # Any other backslash sequences are preserved.
     41   1.4  rillig #
     42   1.4  rillig # The escaping rules for string literals in conditions are completely
     43   1.4  rillig # different though. There, any character may be escaped using a backslash.
     44   1.4  rillig #
     45   1.4  rillig .if ${DEF:D \} \: \$ \\ \) \n } != " } : \$ \\ \\) \\n "
     46   1.4  rillig .  error
     47   1.4  rillig .endif
     48   1.4  rillig 
     49  1.16  rillig # Like in several other places in expressions, when
     50   1.4  rillig # ApplyModifier_Defined calls Var_Parse, double dollars lead to a parse
     51   1.4  rillig # error that is silently ignored.  This makes all dollar signs disappear,
     52  1.16  rillig # except for the last, which is a well-formed expression.
     53   1.4  rillig #
     54   1.4  rillig .if ${DEF:D$$$$$${DEF}} != "defined"
     55   1.4  rillig .  error
     56   1.4  rillig .endif
     57   1.4  rillig 
     58   1.4  rillig # Any other text is written without any further escaping.  In contrast
     59   1.4  rillig # to the :M modifier, parentheses and braces do not need to be nested.
     60   1.4  rillig # Instead, the :D modifier is implemented sanely by parsing nested
     61  1.14  rillig # expressions as such, without trying any shortcuts. See ParseModifier_Match
     62   1.4  rillig # for an inferior variant.
     63   1.4  rillig #
     64   1.4  rillig .if ${DEF:D!&((((} != "!&(((("
     65   1.4  rillig .  error
     66   1.4  rillig .endif
     67   1.4  rillig 
     68   1.5  rillig # The :D modifier is often used in combination with the :U modifier.
     69   1.5  rillig # It does not matter in which order the :D and :U modifiers appear.
     70   1.5  rillig .if ${UNDEF:Dyes:Uno} != no
     71   1.5  rillig .  error
     72   1.5  rillig .endif
     73   1.5  rillig .if ${UNDEF:Uno:Dyes} != no
     74   1.5  rillig .  error
     75   1.5  rillig .endif
     76   1.5  rillig .if ${DEF:Dyes:Uno} != yes
     77   1.5  rillig .  error
     78   1.5  rillig .endif
     79   1.5  rillig .if ${DEF:Uno:Dyes} != yes
     80   1.5  rillig .  error
     81   1.5  rillig .endif
     82   1.5  rillig 
     83   1.6  rillig # Since the variable with the empty name is never defined, the :D modifier
     84   1.6  rillig # can be used to add comments in the middle of an expression.  That
     85   1.6  rillig # expression always evaluates to an empty string.
     86   1.6  rillig .if ${:D This is a comment. } != ""
     87   1.6  rillig .  error
     88   1.6  rillig .endif
     89   1.6  rillig 
     90   1.4  rillig # TODO: Add more tests for parsing the plain text part, to cover each branch
     91   1.4  rillig # of ApplyModifier_Defined.
     92   1.4  rillig 
     93   1.8  rillig # The :D and :U modifiers behave differently from the :@var@ modifier in
     94   1.8  rillig # that they preserve dollars in a ':=' assignment.  This is because
     95  1.11  rillig # ApplyModifier_Defined passes the emode unmodified to Var_Parse, unlike
     96   1.8  rillig # ApplyModifier_Loop, which uses ParseModifierPart, which in turn removes
     97  1.11  rillig # the keepDollar flag from emode.
     98   1.8  rillig #
     99   1.8  rillig # XXX: This inconsistency is documented nowhere.
    100   1.8  rillig .MAKEFLAGS: -dv
    101   1.8  rillig 8_DOLLARS=	$$$$$$$$
    102   1.8  rillig VAR:=		${8_DOLLARS}
    103   1.8  rillig VAR:=		${VAR:D${8_DOLLARS}}
    104   1.8  rillig VAR:=		${VAR:@var@${8_DOLLARS}@}
    105   1.8  rillig .MAKEFLAGS: -d0
    106   1.8  rillig 
    107  1.13  rillig 
    108  1.13  rillig # Before var.c 1.1030 from 2022-08-24, the following expression caused an
    109  1.15  rillig # out-of-bounds read when parsing the indirect ':U' modifier.
    110  1.13  rillig M_U_backslash:=	${:UU\\}
    111  1.13  rillig .if ${:${M_U_backslash}} != "\\"
    112  1.13  rillig .  error
    113  1.13  rillig .endif
    114  1.13  rillig 
    115  1.13  rillig 
    116  1.13  rillig all: .PHONY
    117