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