]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bmake/unit-tests/varmod-defined.mk
Merge bmake-20201117
[FreeBSD/FreeBSD.git] / contrib / bmake / unit-tests / varmod-defined.mk
1 # $NetBSD: varmod-defined.mk,v 1.9 2020/11/12 00:40:55 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 .MAKE.SAVE_DOLLARS=     yes
7
8 DEF=    defined
9 .undef UNDEF
10
11 # Since DEF is defined, the value of the expression is "value", not
12 # "defined".
13 #
14 .if ${DEF:Dvalue} != "value"
15 .  error
16 .endif
17
18 # Since UNDEF is not defined, the "value" is ignored.  Instead of leaving the
19 # expression undefined, it is set to "", exactly to allow the expression to
20 # be used in .if conditions.  In this place, other undefined expressions
21 # would generate an error message.
22 # XXX: Ideally the error message would be "undefined variable", but as of
23 # 2020-08-25 it is "Malformed conditional".
24 #
25 .if ${UNDEF:Dvalue} != ""
26 .  error
27 .endif
28
29 # The modifier text may contain plain text as well as expressions.
30 #
31 .if ${DEF:D<${DEF}>} != "<defined>"
32 .  error
33 .endif
34
35 # Special characters that would be interpreted differently can be escaped.
36 # These are '}' (the closing character of the expression), ':', '$' and '\'.
37 # Any other backslash sequences are preserved.
38 #
39 # The escaping rules for string literals in conditions are completely
40 # different though. There, any character may be escaped using a backslash.
41 #
42 .if ${DEF:D \} \: \$ \\ \) \n } != " } : \$ \\ \\) \\n "
43 .  error
44 .endif
45
46 # Like in several other places in variable expressions, when
47 # ApplyModifier_Defined calls Var_Parse, double dollars lead to a parse
48 # error that is silently ignored.  This makes all dollar signs disappear,
49 # except for the last, which is a well-formed variable expression.
50 #
51 .if ${DEF:D$$$$$${DEF}} != "defined"
52 .  error
53 .endif
54
55 # Any other text is written without any further escaping.  In contrast
56 # to the :M modifier, parentheses and braces do not need to be nested.
57 # Instead, the :D modifier is implemented sanely by parsing nested
58 # expressions as such, without trying any shortcuts. See ApplyModifier_Match
59 # for an inferior variant.
60 #
61 .if ${DEF:D!&((((} != "!&(((("
62 .  error
63 .endif
64
65 # The :D modifier is often used in combination with the :U modifier.
66 # It does not matter in which order the :D and :U modifiers appear.
67 .if ${UNDEF:Dyes:Uno} != no
68 .  error
69 .endif
70 .if ${UNDEF:Uno:Dyes} != no
71 .  error
72 .endif
73 .if ${DEF:Dyes:Uno} != yes
74 .  error
75 .endif
76 .if ${DEF:Uno:Dyes} != yes
77 .  error
78 .endif
79
80 # Since the variable with the empty name is never defined, the :D modifier
81 # can be used to add comments in the middle of an expression.  That
82 # expression always evaluates to an empty string.
83 .if ${:D This is a comment. } != ""
84 .  error
85 .endif
86
87 # TODO: Add more tests for parsing the plain text part, to cover each branch
88 # of ApplyModifier_Defined.
89
90 # The :D and :U modifiers behave differently from the :@var@ modifier in
91 # that they preserve dollars in a ':=' assignment.  This is because
92 # ApplyModifier_Defined passes the eflags unmodified to Var_Parse, unlike
93 # ApplyModifier_Loop, which uses ParseModifierPart, which in turn removes
94 # VARE_KEEP_DOLLAR from eflags.
95 #
96 # XXX: This inconsistency is documented nowhere.
97 .MAKEFLAGS: -dv
98 8_DOLLARS=      $$$$$$$$
99 VAR:=           ${8_DOLLARS}
100 VAR:=           ${VAR:D${8_DOLLARS}}
101 VAR:=           ${VAR:@var@${8_DOLLARS}@}
102 .MAKEFLAGS: -d0
103
104 all:
105         @:;