xref: /freebsd/contrib/bmake/unit-tests/varmod-undefined.mk (revision 6fa42b91ca3f481912af98c4d49c44507eb1b8e1)
1# $NetBSD: varmod-undefined.mk,v 1.11 2024/06/03 02:46:29 sjg Exp $
2#
3# Tests for the :U variable modifier, which returns the given string
4# if the variable is undefined.
5#
6# See also:
7#	directive-for.mk
8#	varmod-defined.mk
9
10# this test depends on
11.MAKE.SAVE_DOLLARS= yes
12
13# The pattern ${:Uword} is heavily used when expanding .for loops.
14#
15# This is how an expanded .for loop looks like.
16# .for word in one
17# .  if ${word} != one
18.if ${:Uone} != one
19# .    error ${word}
20.  error ${:Uone}
21# .  endif
22.endif
23# .endfor
24
25# The expressions in the text of the :U modifier may be arbitrarily
26# nested.
27
28.if ${:U${:Unested}${${${:Udeeply}}}} != nested
29.  error
30.endif
31
32# The nested expressions may contain braces, and these braces don't
33# need to match pairwise.  In the following example, the :S modifier uses '{'
34# as delimiter, which confuses both editors and humans because the opening
35# and closing braces don't match anymore.  It's syntactically valid though.
36# For more similar examples, see varmod-subst.mk, mod-subst-delimiter.
37
38.if ${:U${:Uvalue:S{a{X{}} != vXlue
39.  error
40.endif
41
42# The escaping rules for the :U modifier (left-hand side) and condition
43# string literals (right-hand side) are completely different.
44#
45# In the :U modifier, the backslash only escapes very few characters, all
46# other backslashes are retained.
47#
48# In condition string literals, the backslash always escapes the following
49# character, no matter whether it would be necessary or not.
50#
51# In both contexts, \n is an escaped letter n, not a newline; that's what
52# the .newline variable is for.
53#
54# Whitespace at the edges is preserved, on both sides of the comparison.
55#
56.if ${:U \: \} \$ \\ \a \b \n } != " : } \$ \\ \\a \\b \\n "
57.  error
58.endif
59# An expression enclosed in quotes may be based on an undefined variable.
60.if "${:U \: \} \$ \\ \a \b \n }" != " : } \$ \\ \\a \\b \\n "
61.  error
62.endif
63
64# Even after the :U modifier has been applied, the expression still remembers
65# that it originated from an undefined variable, and the :U modifier can
66# be used to overwrite the value of the expression.
67#
68.if ${UNDEF:Uvalue:S,a,X,} != "vXlue"
69.  error
70.elif ${UNDEF:Uvalue:S,a,X,:Uwas undefined} != "was undefined"
71.  error
72.endif
73
74
75# VARE_PARSE
76.if 0 && ${:U . \: \} \$ \\ ${EXPR}}
77.  error
78.endif
79
80# VARE_EVAL_KEEP_DOLLAR_AND_UNDEFINED
81SUBST:=		${:U . \: \} \$ \\ ${EXPR}}
82${:U }=		<space>
83EXPR=		<expr>
84.if ${SUBST} != " . : } <space>\\ "
85.  error
86.endif
87
888_DOLLAR=	$$$$$$$$
89.if ${8_DOLLAR} != "\$\$\$\$"
90.  error
91.endif
92.if ${:U${8_DOLLAR}} != "\$\$\$\$"
93.  error
94.endif
95.if ${x:L:@_@${8_DOLLAR}@} != "\$\$\$\$"
96.  error
97.endif
98EXPR:=		${8_DOLLAR}
99.if ${EXPR} != "\$\$\$\$"
100.  error
101.endif
102EXPR:=		${:U${8_DOLLAR}}
103.if ${EXPR} != "\$\$\$\$"
104.  error
105.endif
106# VARE_EVAL_KEEP_UNDEFINED
107EXPR:=		${x:L:@_@${8_DOLLAR}@}
108.if ${EXPR} != "\$\$"
109.  error
110.endif
111
112
113all: .PHONY
114