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