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