1 1.3 rillig # $NetBSD: varmod-no-match.mk,v 1.3 2023/02/26 06:08:06 rillig Exp $ 2 1.1 rillig # 3 1.3 rillig # Tests for the expression modifier ':N', which filters words that do not 4 1.3 rillig # match the given pattern. 5 1.3 rillig 6 1.3 rillig 7 1.3 rillig # Keep all words except for 'two'. 8 1.3 rillig .if ${:U one two three :Ntwo} != "one three" 9 1.3 rillig . error 10 1.3 rillig .endif 11 1.3 rillig 12 1.3 rillig # Keep all words except those starting with 't'. 13 1.3 rillig # See varmod-match.mk for the details of pattern matching. 14 1.3 rillig .if ${:U one two three four six :Nt*} != "one four six" 15 1.3 rillig . error 16 1.3 rillig .endif 17 1.3 rillig 18 1.3 rillig 19 1.3 rillig # Idiom: normalize whitespace 20 1.3 rillig # 21 1.3 rillig # The modifier ':N' can be used with an empty pattern. As that pattern never 22 1.3 rillig # matches a word, the only effect is that the string is split into words and 23 1.3 rillig # then joined again, thereby normalizing whitespace around and between the 24 1.3 rillig # words. And even though the 'N' in ':N' might serve as a mnemonic for 25 1.3 rillig # "normalize whitespace", this idiom is not used in practice, resorting to the 26 1.3 rillig # much more common ':M*' to "select all words" instead. 27 1.3 rillig .if ${:U :N} != "" 28 1.3 rillig . error 29 1.3 rillig .endif 30 1.3 rillig .if ${:U one two three :N} != "one two three" 31 1.3 rillig . error 32 1.3 rillig .endif 33 1.3 rillig .if ${:U one two three :M*} != "one two three" 34 1.3 rillig . error 35 1.3 rillig .endif 36 1.3 rillig 37 1.3 rillig 38 1.3 rillig # Idiom: single-word expression equals any of several words or patterns 39 1.3 rillig # 40 1.3 rillig # If an expression is guaranteed to consist of a single word, the modifier 41 1.3 rillig # ':N' can be chained to compare the expression to several words or even 42 1.3 rillig # patterns in a sequence. If one of the patterns matches, the final 43 1.3 rillig # expression will be the empty string. 44 1.3 rillig # 45 1.3 rillig .if ${:U word :None:Ntwo:Nthree} != "" 46 1.3 rillig # good 47 1.3 rillig .else 48 1.3 rillig . error 49 1.3 rillig .endif 50 1.3 rillig .if ${:U two :None:Ntwo:Nthree} != "" 51 1.3 rillig . error 52 1.3 rillig .else 53 1.3 rillig # good 54 1.3 rillig .endif 55 1.3 rillig # 56 1.3 rillig # The modifier ':N' is seldom used in general since positive matches with ':M' 57 1.3 rillig # are easier to grasp. Chaining the ':N' modifier is even more difficult to 58 1.3 rillig # grasp due to the many negations involved. 59 1.3 rillig # 60 1.3 rillig # The final '!= ""' adds to the confusion because at first glance, the 61 1.3 rillig # condition may look like '${VAR} != ""', which for a single-word variable is 62 1.3 rillig # always true. 63 1.3 rillig # 64 1.3 rillig # The '!= ""' can be omitted if the expression cannot have the numeric value 65 1.3 rillig # 0, which is common in practice. In that form, each ':N' can be pronounced 66 1.3 rillig # as 'neither' or 'nor', which makes the expression sound more natural. 67 1.3 rillig # 68 1.3 rillig .if ${:U word :None:Ntwo:Nthree} 69 1.3 rillig # good 70 1.3 rillig .else 71 1.3 rillig . error 72 1.3 rillig .endif 73 1.3 rillig .if ${:U two :None:Ntwo:Nthree} 74 1.3 rillig . error 75 1.3 rillig .else 76 1.3 rillig # good 77 1.3 rillig .endif 78 1.3 rillig # 79 1.3 rillig # Replacing the '${...} != ""' with '!empty(...)' doesn't improve the 80 1.3 rillig # situation as the '!' adds another level of negations, and the word 'empty' 81 1.3 rillig # is a negation on its own, thereby creating a triple negation. Furthermore, 82 1.3 rillig # due to the '!empty', the expression to be evaluated no longer starts with 83 1.3 rillig # '$' and is thus more difficult to spot quickly. 84 1.3 rillig # 85 1.3 rillig .if !empty(:U word :None:Ntwo:Nthree) 86 1.3 rillig # good 87 1.3 rillig .else 88 1.3 rillig . error 89 1.3 rillig .endif 90 1.3 rillig .if !empty(:U two :None:Ntwo:Nthree) 91 1.3 rillig . error 92 1.3 rillig .else 93 1.3 rillig # good 94 1.3 rillig .endif 95 1.1 rillig 96 1.1 rillig 97 1.1 rillig all: 98