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