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