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 81 SUBST:= ${:U . \: \} \$ \\ ${EXPR}} 82 ${:U }= <space> 83 EXPR= <expr> 84 .if ${SUBST} != " . : } <space>\\ " 85 . error 86 .endif 87 88 8_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 98 EXPR:= ${8_DOLLAR} 99 .if ${EXPR} != "\$\$\$\$" 100 . error 101 .endif 102 EXPR:= ${:U${8_DOLLAR}} 103 .if ${EXPR} != "\$\$\$\$" 104 . error 105 .endif 106 # VARE_EVAL_KEEP_UNDEFINED 107 EXPR:= ${x:L:@_@${8_DOLLAR}@} 108 .if ${EXPR} != "\$\$" 109 . error 110 .endif 111 112 113 all: .PHONY 114