1# $NetBSD: varmod-defined.mk,v 1.9 2020/11/12 00:40:55 rillig Exp $ 2# 3# Tests for the :D variable modifier, which returns the given string 4# if the variable is defined. It is closely related to the :U modifier. 5 6.MAKE.SAVE_DOLLARS= yes 7 8DEF= defined 9.undef UNDEF 10 11# Since DEF is defined, the value of the expression is "value", not 12# "defined". 13# 14.if ${DEF:Dvalue} != "value" 15. error 16.endif 17 18# Since UNDEF is not defined, the "value" is ignored. Instead of leaving the 19# expression undefined, it is set to "", exactly to allow the expression to 20# be used in .if conditions. In this place, other undefined expressions 21# would generate an error message. 22# XXX: Ideally the error message would be "undefined variable", but as of 23# 2020-08-25 it is "Malformed conditional". 24# 25.if ${UNDEF:Dvalue} != "" 26. error 27.endif 28 29# The modifier text may contain plain text as well as expressions. 30# 31.if ${DEF:D<${DEF}>} != "<defined>" 32. error 33.endif 34 35# Special characters that would be interpreted differently can be escaped. 36# These are '}' (the closing character of the expression), ':', '$' and '\'. 37# Any other backslash sequences are preserved. 38# 39# The escaping rules for string literals in conditions are completely 40# different though. There, any character may be escaped using a backslash. 41# 42.if ${DEF:D \} \: \$ \\ \) \n } != " } : \$ \\ \\) \\n " 43. error 44.endif 45 46# Like in several other places in variable expressions, when 47# ApplyModifier_Defined calls Var_Parse, double dollars lead to a parse 48# error that is silently ignored. This makes all dollar signs disappear, 49# except for the last, which is a well-formed variable expression. 50# 51.if ${DEF:D$$$$$${DEF}} != "defined" 52. error 53.endif 54 55# Any other text is written without any further escaping. In contrast 56# to the :M modifier, parentheses and braces do not need to be nested. 57# Instead, the :D modifier is implemented sanely by parsing nested 58# expressions as such, without trying any shortcuts. See ApplyModifier_Match 59# for an inferior variant. 60# 61.if ${DEF:D!&((((} != "!&((((" 62. error 63.endif 64 65# The :D modifier is often used in combination with the :U modifier. 66# It does not matter in which order the :D and :U modifiers appear. 67.if ${UNDEF:Dyes:Uno} != no 68. error 69.endif 70.if ${UNDEF:Uno:Dyes} != no 71. error 72.endif 73.if ${DEF:Dyes:Uno} != yes 74. error 75.endif 76.if ${DEF:Uno:Dyes} != yes 77. error 78.endif 79 80# Since the variable with the empty name is never defined, the :D modifier 81# can be used to add comments in the middle of an expression. That 82# expression always evaluates to an empty string. 83.if ${:D This is a comment. } != "" 84. error 85.endif 86 87# TODO: Add more tests for parsing the plain text part, to cover each branch 88# of ApplyModifier_Defined. 89 90# The :D and :U modifiers behave differently from the :@var@ modifier in 91# that they preserve dollars in a ':=' assignment. This is because 92# ApplyModifier_Defined passes the eflags unmodified to Var_Parse, unlike 93# ApplyModifier_Loop, which uses ParseModifierPart, which in turn removes 94# VARE_KEEP_DOLLAR from eflags. 95# 96# XXX: This inconsistency is documented nowhere. 97.MAKEFLAGS: -dv 988_DOLLARS= $$$$$$$$ 99VAR:= ${8_DOLLARS} 100VAR:= ${VAR:D${8_DOLLARS}} 101VAR:= ${VAR:@var@${8_DOLLARS}@} 102.MAKEFLAGS: -d0 103 104all: 105 @:; 106