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