xref: /freebsd/contrib/bmake/unit-tests/varmod-undefined.mk (revision fb3ef04d2028110f06d68b09009f1f2ca0f4128e)
1# $NetBSD: varmod-undefined.mk,v 1.8 2022/08/06 21:26:05 rillig 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# The pattern ${:Uword} is heavily used when expanding .for loops.
11#
12# This is how an expanded .for loop looks like.
13# .for word in one
14# .  if ${word} != one
15.if ${:Uone} != one
16# .    error ${word}
17.  error ${:Uone}
18# .  endif
19.endif
20# .endfor
21
22# The variable expressions in the text of the :U modifier may be arbitrarily
23# nested.
24
25.if ${:U${:Unested}${${${:Udeeply}}}} != nested
26.  error
27.endif
28
29# The nested variable expressions may contain braces, and these braces don't
30# need to match pairwise.  In the following example, the :S modifier uses '{'
31# as delimiter, which confuses both editors and humans because the opening
32# and closing braces don't match anymore.  It's syntactically valid though.
33# For more similar examples, see varmod-subst.mk, mod-subst-delimiter.
34
35.if ${:U${:Uvalue:S{a{X{}} != vXlue
36.  error
37.endif
38
39# The escaping rules for the :U modifier (left-hand side) and condition
40# string literals (right-hand side) are completely different.
41#
42# In the :U modifier, the backslash only escapes very few characters, all
43# other backslashes are retained.
44#
45# In condition string literals, the backslash always escapes the following
46# character, no matter whether it would be necessary or not.
47#
48# In both contexts, \n is an escaped letter n, not a newline; that's what
49# the .newline variable is for.
50#
51# Whitespace at the edges is preserved, on both sides of the comparison.
52#
53.if ${:U \: \} \$ \\ \a \b \n } != " : } \$ \\ \\a \\b \\n "
54.  error
55.endif
56
57# Even after the :U modifier has been applied, the expression still remembers
58# that it originated from an undefined variable, and the :U modifier can
59# be used to overwrite the value of the expression.
60#
61.if ${UNDEF:Uvalue:S,a,X,} != "vXlue"
62.  error
63.elif ${UNDEF:Uvalue:S,a,X,:Uwas undefined} != "was undefined"
64.  error
65.endif
66
67all:
68	@:;
69