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