xref: /freebsd/contrib/bmake/unit-tests/varmod-undefined.mk (revision 8d5c8e21c690b35d0a9a604d6b886fba222cd2fe)
1*8d5c8e21SSimon J. Gerraty# $NetBSD: varmod-undefined.mk,v 1.11 2024/06/03 02:46:29 sjg Exp $
22c3632d1SSimon J. Gerraty#
32c3632d1SSimon J. Gerraty# Tests for the :U variable modifier, which returns the given string
42c3632d1SSimon J. Gerraty# if the variable is undefined.
52c3632d1SSimon J. Gerraty#
6956e45f6SSimon J. Gerraty# See also:
7e2eeea75SSimon J. Gerraty#	directive-for.mk
8956e45f6SSimon J. Gerraty#	varmod-defined.mk
92c3632d1SSimon J. Gerraty
10*8d5c8e21SSimon J. Gerraty# this test depends on
11*8d5c8e21SSimon J. Gerraty.MAKE.SAVE_DOLLARS= yes
12*8d5c8e21SSimon J. Gerraty
13956e45f6SSimon J. Gerraty# The pattern ${:Uword} is heavily used when expanding .for loops.
14956e45f6SSimon J. Gerraty#
152c3632d1SSimon J. Gerraty# This is how an expanded .for loop looks like.
162c3632d1SSimon J. Gerraty# .for word in one
172c3632d1SSimon J. Gerraty# .  if ${word} != one
182c3632d1SSimon J. Gerraty.if ${:Uone} != one
19956e45f6SSimon J. Gerraty# .    error ${word}
202c3632d1SSimon J. Gerraty.  error ${:Uone}
21956e45f6SSimon J. Gerraty# .  endif
222c3632d1SSimon J. Gerraty.endif
23956e45f6SSimon J. Gerraty# .endfor
242c3632d1SSimon J. Gerraty
25d5e0a182SSimon J. Gerraty# The expressions in the text of the :U modifier may be arbitrarily
262c3632d1SSimon J. Gerraty# nested.
272c3632d1SSimon J. Gerraty
282c3632d1SSimon J. Gerraty.if ${:U${:Unested}${${${:Udeeply}}}} != nested
292c3632d1SSimon J. Gerraty.  error
302c3632d1SSimon J. Gerraty.endif
312c3632d1SSimon J. Gerraty
32d5e0a182SSimon J. Gerraty# The nested expressions may contain braces, and these braces don't
332c3632d1SSimon J. Gerraty# need to match pairwise.  In the following example, the :S modifier uses '{'
342c3632d1SSimon J. Gerraty# as delimiter, which confuses both editors and humans because the opening
354fde40d9SSimon J. Gerraty# and closing braces don't match anymore.  It's syntactically valid though.
362c3632d1SSimon J. Gerraty# For more similar examples, see varmod-subst.mk, mod-subst-delimiter.
372c3632d1SSimon J. Gerraty
382c3632d1SSimon J. Gerraty.if ${:U${:Uvalue:S{a{X{}} != vXlue
392c3632d1SSimon J. Gerraty.  error
402c3632d1SSimon J. Gerraty.endif
412c3632d1SSimon J. Gerraty
422c3632d1SSimon J. Gerraty# The escaping rules for the :U modifier (left-hand side) and condition
432c3632d1SSimon J. Gerraty# string literals (right-hand side) are completely different.
442c3632d1SSimon J. Gerraty#
452c3632d1SSimon J. Gerraty# In the :U modifier, the backslash only escapes very few characters, all
462c3632d1SSimon J. Gerraty# other backslashes are retained.
472c3632d1SSimon J. Gerraty#
482c3632d1SSimon J. Gerraty# In condition string literals, the backslash always escapes the following
492c3632d1SSimon J. Gerraty# character, no matter whether it would be necessary or not.
502c3632d1SSimon J. Gerraty#
512c3632d1SSimon J. Gerraty# In both contexts, \n is an escaped letter n, not a newline; that's what
522c3632d1SSimon J. Gerraty# the .newline variable is for.
532c3632d1SSimon J. Gerraty#
542c3632d1SSimon J. Gerraty# Whitespace at the edges is preserved, on both sides of the comparison.
55956e45f6SSimon J. Gerraty#
562c3632d1SSimon J. Gerraty.if ${:U \: \} \$ \\ \a \b \n } != " : } \$ \\ \\a \\b \\n "
572c3632d1SSimon J. Gerraty.  error
582c3632d1SSimon J. Gerraty.endif
59*8d5c8e21SSimon J. Gerraty# An expression enclosed in quotes may be based on an undefined variable.
60*8d5c8e21SSimon J. Gerraty.if "${:U \: \} \$ \\ \a \b \n }" != " : } \$ \\ \\a \\b \\n "
61*8d5c8e21SSimon J. Gerraty.  error
62*8d5c8e21SSimon J. Gerraty.endif
632c3632d1SSimon J. Gerraty
64956e45f6SSimon J. Gerraty# Even after the :U modifier has been applied, the expression still remembers
65956e45f6SSimon J. Gerraty# that it originated from an undefined variable, and the :U modifier can
66956e45f6SSimon J. Gerraty# be used to overwrite the value of the expression.
67956e45f6SSimon J. Gerraty#
68956e45f6SSimon J. Gerraty.if ${UNDEF:Uvalue:S,a,X,} != "vXlue"
69956e45f6SSimon J. Gerraty.  error
70956e45f6SSimon J. Gerraty.elif ${UNDEF:Uvalue:S,a,X,:Uwas undefined} != "was undefined"
71956e45f6SSimon J. Gerraty.  error
72956e45f6SSimon J. Gerraty.endif
73956e45f6SSimon J. Gerraty
74*8d5c8e21SSimon J. Gerraty
75*8d5c8e21SSimon J. Gerraty# VARE_PARSE
76*8d5c8e21SSimon J. Gerraty.if 0 && ${:U . \: \} \$ \\ ${EXPR}}
77*8d5c8e21SSimon J. Gerraty.  error
78*8d5c8e21SSimon J. Gerraty.endif
79*8d5c8e21SSimon J. Gerraty
80*8d5c8e21SSimon J. Gerraty# VARE_EVAL_KEEP_DOLLAR_AND_UNDEFINED
81*8d5c8e21SSimon J. GerratySUBST:=		${:U . \: \} \$ \\ ${EXPR}}
82*8d5c8e21SSimon J. Gerraty${:U }=		<space>
83*8d5c8e21SSimon J. GerratyEXPR=		<expr>
84*8d5c8e21SSimon J. Gerraty.if ${SUBST} != " . : } <space>\\ "
85*8d5c8e21SSimon J. Gerraty.  error
86*8d5c8e21SSimon J. Gerraty.endif
87*8d5c8e21SSimon J. Gerraty
88*8d5c8e21SSimon J. Gerraty8_DOLLAR=	$$$$$$$$
89*8d5c8e21SSimon J. Gerraty.if ${8_DOLLAR} != "\$\$\$\$"
90*8d5c8e21SSimon J. Gerraty.  error
91*8d5c8e21SSimon J. Gerraty.endif
92*8d5c8e21SSimon J. Gerraty.if ${:U${8_DOLLAR}} != "\$\$\$\$"
93*8d5c8e21SSimon J. Gerraty.  error
94*8d5c8e21SSimon J. Gerraty.endif
95*8d5c8e21SSimon J. Gerraty.if ${x:L:@_@${8_DOLLAR}@} != "\$\$\$\$"
96*8d5c8e21SSimon J. Gerraty.  error
97*8d5c8e21SSimon J. Gerraty.endif
98*8d5c8e21SSimon J. GerratyEXPR:=		${8_DOLLAR}
99*8d5c8e21SSimon J. Gerraty.if ${EXPR} != "\$\$\$\$"
100*8d5c8e21SSimon J. Gerraty.  error
101*8d5c8e21SSimon J. Gerraty.endif
102*8d5c8e21SSimon J. GerratyEXPR:=		${:U${8_DOLLAR}}
103*8d5c8e21SSimon J. Gerraty.if ${EXPR} != "\$\$\$\$"
104*8d5c8e21SSimon J. Gerraty.  error
105*8d5c8e21SSimon J. Gerraty.endif
106*8d5c8e21SSimon J. Gerraty# VARE_EVAL_KEEP_UNDEFINED
107*8d5c8e21SSimon J. GerratyEXPR:=		${x:L:@_@${8_DOLLAR}@}
108*8d5c8e21SSimon J. Gerraty.if ${EXPR} != "\$\$"
109*8d5c8e21SSimon J. Gerraty.  error
110*8d5c8e21SSimon J. Gerraty.endif
111*8d5c8e21SSimon J. Gerraty
112*8d5c8e21SSimon J. Gerraty
113*8d5c8e21SSimon J. Gerratyall: .PHONY
114