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